From 5b5bdc796f0af04fd8ae701859fbd480905c8053 Mon Sep 17 00:00:00 2001 From: DuckDB Labs GitHub Bot Date: Thu, 11 Jun 2026 14:24:43 +0000 Subject: [PATCH 1/2] Update vendored DuckDB sources to b87f30f0c1 --- .../function/table/version/pragma_version.cpp | 6 +- .../duckdb/parser/peg/inlined_grammar.hpp | 3245 ++++++++--------- .../src/include/duckdb/planner/binder.hpp | 6 +- .../transformer/transform_create_trigger.cpp | 4 + src/duckdb/src/planner/binder.cpp | 150 - .../query_node/bind_trigger_expansion.cpp | 395 ++ .../planner/binder/statement/bind_delete.cpp | 2 +- .../planner/binder/statement/bind_insert.cpp | 2 +- .../planner/binder/statement/bind_update.cpp | 2 +- ...ion_core_functions_aggregate_algebraic.cpp | 4 +- ..._core_functions_aggregate_distributive.cpp | 16 +- ...sion_core_functions_aggregate_holistic.cpp | 4 +- ...ension_core_functions_aggregate_nested.cpp | 4 +- ...on_core_functions_aggregate_regression.cpp | 10 +- ...b_extension_core_functions_scalar_date.cpp | 18 +- ..._extension_core_functions_scalar_debug.cpp | 4 +- ...xtension_core_functions_scalar_generic.cpp | 16 +- ...b_extension_core_functions_scalar_list.cpp | 16 +- ...ub_extension_core_functions_scalar_map.cpp | 12 +- ...extension_core_functions_scalar_string.cpp | 48 +- ...extension_core_functions_scalar_struct.cpp | 6 +- ...b_extension_icu_third_party_icu_common.cpp | 216 +- .../ub_extension_icu_third_party_icu_i18n.cpp | 176 +- .../ub_extension_json_json_functions.cpp | 40 +- src/duckdb/ub_extension_parquet_decoder.cpp | 8 +- src/duckdb/ub_extension_parquet_reader.cpp | 14 +- src/duckdb/ub_extension_parquet_writer.cpp | 12 +- .../ub_extension_parquet_writer_variant.cpp | 4 +- .../ub_src_planner_binder_query_node.cpp | 2 + 29 files changed, 2333 insertions(+), 2109 deletions(-) create mode 100644 src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 38725657a..058e63373 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 "0-dev8488" +#define DUCKDB_PATCH_VERSION "0-dev8509" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 6 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 1 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v1.6.0-dev8488" +#define DUCKDB_VERSION "v1.6.0-dev8509" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "ff62f2bc89" +#define DUCKDB_SOURCE_ID "b87f30f0c1" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp index f84886966..50507a22f 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp @@ -4,1642 +4,1615 @@ namespace duckdb { const char INLINED_PEG_GRAMMAR[] = { - "Program <- TopLevelStatement*\n" - "TopLevelStatement <- Statement? (';'+ / EndOfInput)\n" - "Statement <-\n" - " CreateStatement /\n" - " SelectStatement /\n" - " SetStatement /\n" - " PragmaStatement /\n" - " CallStatement /\n" - " InsertStatement /\n" - " DropStatement /\n" - " CopyStatement /\n" - " ExplainStatement /\n" - " UpdateStatement /\n" - " PrepareStatement /\n" - " ExecuteStatement /\n" - " AlterStatement /\n" - " TransactionStatement /\n" - " DeleteStatement /\n" - " AttachStatement /\n" - " UseStatement /\n" - " DetachStatement /\n" - " CheckpointStatement /\n" - " VacuumStatement /\n" - " ResetStatement /\n" - " ExportStatement /\n" - " ImportStatement /\n" - " CommentStatement /\n" - " DeallocateStatement /\n" - " TruncateStatement /\n" - " LoadStatement /\n" - " InstallStatement /\n" - " UpdateExtensionsStatement /\n" - " AnalyzeStatement /\n" - " MergeIntoStatement /\n" - " ConnectStatement /\n" - " DisconnectStatement /\n" - " ExpressionStatement\n" - "ExpressionStatement <- List(ExpressionAlias)\n" - "ExpressionAlias <- ColIdExpression / ExpressionAsCollabel / Expression\n" - "CatalogName <- Identifier\n" - "SchemaName <- Identifier\n" - "ReservedSchemaName <- Identifier\n" - "TableName <- Identifier\n" - "ReservedTableName <- Identifier\n" - "ReservedIdentifier <- Identifier\n" - "ColumnName <- Identifier\n" - "ReservedColumnName <- Identifier\n" - "IndexName <- Identifier\n" - "ReservedIndexName <- Identifier\n" - "SettingName <- Identifier\n" - "PragmaName <- Identifier\n" - "FunctionName <- Identifier\n" - "ReservedFunctionName <- Identifier\n" - "ReservedTypeName <- Identifier\n" - "TableFunctionName <- Identifier\n" - "ConstraintName <- ColIdOrString\n" - "SequenceName <- Identifier\n" - "CollationName <- Identifier\n" - "CopyOptionName <- ColLabel\n" - "NumberLiteral <- < [+-]?[0-9]*([.][0-9]*)? >\n" - "StringLiteral <- '\\'' [^\\']* '\\''\n" - "Type <- TypeVariations ArrayBounds*\n" - "TypeVariations <- TimeType / IntervalType / BitType / RowType / VariantType / MapType / GeometryType / UnionType " - "/ NumericType / SetofType / SimpleType\n" - "SimpleType <- CharacterSimpleType / QualifiedSimpleType\n" - "CharacterSimpleType <- CharacterType TypeModifiers?\n" - "QualifiedSimpleType <- QualifiedTypeName TypeModifiers?\n" - "CharacterType <- ('CHARACTER' 'VARYING'?) /\n" - " ('CHAR' 'VARYING'?) /\n" - " ('NATIONAL' 'CHARACTER' 'VARYING'?) /\n" - " ('NATIONAL' 'CHAR' 'VARYING'?) /\n" - " ('NCHAR' 'VARYING'?) /\n" - " 'VARCHAR'\n" - "IntervalType <- IntervalInterval / IntervalNumber\n" - "IntervalInterval <- IntervalWithSpecifier / IntervalWithoutSpecifier\n" - "IntervalWithSpecifier <- IntervalWithRangeSpecifier / IntervalWithSimpleSpecifier\n" - "IntervalWithRangeSpecifier <- 'INTERVAL' IntervalToIntervalAsType\n" - "IntervalWithSimpleSpecifier <- 'INTERVAL' Interval\n" - "IntervalWithoutSpecifier <- 'INTERVAL'\n" - "IntervalToIntervalAsType <- (YearKeyword 'TO' MonthKeyword) /\n" - " (DayKeyword 'TO' HourKeyword) /\n" - " (DayKeyword 'TO' MinuteKeyword) /\n" - " (DayKeyword 'TO' SecondKeyword) /\n" - " (HourKeyword 'TO' MinuteKeyword) /\n" - " (HourKeyword 'TO' SecondKeyword) /\n" - " (MinuteKeyword 'TO' SecondKeyword)\n" - "IntervalNumber <- 'INTERVAL' Parens(NumberLiteral)\n" - "YearKeyword <- 'YEAR' / 'YEARS'\n" - "MonthKeyword <- 'MONTH' / 'MONTHS'\n" - "DayKeyword <- 'DAY' / 'DAYS'\n" - "HourKeyword <- 'HOUR' / 'HOURS'\n" - "MinuteKeyword <- 'MINUTE' / 'MINUTES'\n" - "SecondKeyword <- 'SECOND' / 'SECONDS'\n" - "MillisecondKeyword <- 'MILLISECOND' / 'MILLISECONDS'\n" - "MicrosecondKeyword <- 'MICROSECOND' / 'MICROSECONDS'\n" - "WeekKeyword <- 'WEEK' / 'WEEKS'\n" - "QuarterKeyword <- 'QUARTER' / 'QUARTERS'\n" - "DecadeKeyword <- 'DECADE' / 'DECADES'\n" - "CenturyKeyword <- 'CENTURY' / 'CENTURIES'\n" - "MillenniumKeyword <- 'MILLENNIUM' / 'MILLENNIA'\n" - "Interval <- IntervalToInterval /\n" - " YearKeyword /\n" - " MonthKeyword /\n" - " DayKeyword /\n" - " HourKeyword /\n" - " MinuteKeyword /\n" - " SecondKeyword /\n" - " MillisecondKeyword /\n" - " MicrosecondKeyword /\n" - " WeekKeyword /\n" - " QuarterKeyword /\n" - " DecadeKeyword /\n" - " CenturyKeyword /\n" - " MillenniumKeyword\n" - "IntervalToInterval <- YearToMonth /\n" - " DayToHour /\n" - " DayToMinute /\n" - " DayToSecond /\n" - " HourToMinute /\n" - " HourToSecond /\n" - " MinuteToSecond\n" - "YearToMonth <- YearKeyword 'TO' MonthKeyword\n" - "DayToHour <- DayKeyword 'TO' HourKeyword\n" - "DayToMinute <- DayKeyword 'TO' MinuteKeyword\n" - "DayToSecond <- DayKeyword 'TO' SecondKeyword\n" - "HourToMinute <- HourKeyword 'TO' MinuteKeyword\n" - "HourToSecond <- HourKeyword 'TO' SecondKeyword\n" - "MinuteToSecond <- MinuteKeyword 'TO' SecondKeyword\n" - "BitType <- 'BIT' 'VARYING'? Parens(List(Expression))?\n" - "GeometryType <- 'GEOMETRY' Parens(Expression)?\n" - "VariantType <- 'VARIANT'\n" - "NumericType <- SimpleNumericType / DecimalNumericType\n" - "SimpleNumericType <- IntType / IntegerType / SmallintType /\n" - " BigintType / RealType / BooleanType / DoubleType\n" - "DecimalNumericType <- FloatType / DecimalType / DecType / NumericModType\n" - "IntType <- 'INT'\n" - "IntegerType <- 'INTEGER'\n" - "SmallintType <- 'SMALLINT'\n" - "BigintType <- 'BIGINT'\n" - "RealType <- 'REAL'\n" - "BooleanType <- 'BOOLEAN'\n" - "DoubleType <- ('DOUBLE' 'PRECISION')\n" - "FloatType <- 'FLOAT' Parens(NumberLiteral)?\n" - "DecimalType <- 'DECIMAL' TypeModifiers?\n" - "DecType <- 'DEC' TypeModifiers?\n" - "NumericModType <- 'NUMERIC' TypeModifiers?\n" - "QualifiedTypeName <- CatalogReservedSchemaTypeName / SchemaReservedTypeName / TypeNameAsQualifiedName\n" - "TypeNameAsQualifiedName <- TypeName\n" - "CatalogReservedSchemaTypeName <- CatalogQualification ReservedSchemaQualification ReservedTypeName\n" - "SchemaReservedTypeName <- SchemaQualification ReservedTypeName\n" - "TypeModifiers <- Parens(List(Expression)?)\n" - "RowType <- RowOrStruct ColIdTypeList\n" - "SetofType <- 'SETOF' Type\n" - "UnionType <- 'UNION' ColIdTypeList\n" - "ColIdTypeList <- Parens(List(ColIdType))\n" - "MapType <- 'MAP' Parens(List(Type))\n" - "ColIdType <- ColId Type\n" - "ArrayBounds <- SquareBracketsArray / ArrayKeyword\n" - "ArrayKeyword <- 'ARRAY'\n" - "SquareBracketsArray <- '[' Expression? ']'\n" - "TimeType <- TimeOrTimestamp TypeModifiers? TimeZone?\n" - "TimeOrTimestamp <- TimeTypeId / TimestampTypeId\n" - "TimeTypeId <- 'TIME'\n" - "TimestampTypeId <- 'TIMESTAMP'\n" - "TimeZone <- WithOrWithout 'TIME' 'ZONE'\n" - "WithOrWithout <- WithRule / WithoutRule\n" - "WithRule <- 'WITH'\n" - "WithoutRule <- 'WITHOUT'\n" - "RowOrStruct <- 'ROW' / 'STRUCT'\n" - "# internal definitions\n" - "%whitespace <- [ \\t\\n\\r]*\n" - "List(D) <- D (',' D)* ','?\n" - "Parens(D) <- '(' D ')'\n" - "UnreservedKeyword <- 'ABORT' /\n" - "'ABSOLUTE' /\n" - "'ACCESS' /\n" - "'ACTION' /\n" - "'ADD' /\n" - "'ADMIN' /\n" - "'AFTER' /\n" - "'AGGREGATE' /\n" - "'ALSO' /\n" - "'ALTER' /\n" - "'ALWAYS' /\n" - "'ASSERTION' /\n" - "'ASSIGNMENT' /\n" - "'ATTACH' /\n" - "'ATTRIBUTE' /\n" - "'BACKWARD' /\n" - "'BEFORE' /\n" - "'BEGIN' /\n" - "'CACHE' /\n" - "'CALL' /\n" - "'CALLED' /\n" - "'CASCADE' /\n" - "'CASCADED' /\n" - "'CATALOG' /\n" - "'CENTURY' /\n" - "'CENTURIES' /\n" - "'CHAIN' /\n" - "'CHARACTERISTICS' /\n" - "'CHECKPOINT' /\n" - "'CLASS' /\n" - "'CLOSE' /\n" - "'CLUSTER' /\n" - "'COMMENT' /\n" - "'COMMENTS' /\n" - "'COMMIT' /\n" - "'COMMITTED' /\n" - "'COMPRESSION' /\n" - "'CONFIGURATION' /\n" - "'CONFLICT' /\n" - "'CONNECT' /\n" - "'CONNECTION' /\n" - "'CONSTRAINTS' /\n" - "'CONTENT' /\n" - "'CONTINUE' /\n" - "'CONVERSION' /\n" - "'COPY' /\n" - "'COST' /\n" - "'CSV' /\n" - "'CUBE' /\n" - "'CURRENT' /\n" - "'CURSOR' /\n" - "'CYCLE' /\n" - "'DATA' /\n" - "'DATABASE' /\n" - "'DAY' /\n" - "'DAYS' /\n" - "'DEALLOCATE' /\n" - "'DECADE' /\n" - "'DECADES' /\n" - "'DECLARE' /\n" - "'DEFAULTS' /\n" - "'DEFERRED' /\n" - "'DEFINER' /\n" - "'DELETE' /\n" - "'DELIMITER' /\n" - "'DELIMITERS' /\n" - "'DEPENDS' /\n" - "'DETACH' /\n" - "'DICTIONARY' /\n" - "'DISABLE' /\n" - "'DISCARD' /\n" - "'DISCONNECT' /\n" - "'DOCUMENT' /\n" - "'DOMAIN' /\n" - "'DOUBLE' /\n" - "'DROP' /\n" - "'EACH' /\n" - "'ENABLE' /\n" - "'ENCODING' /\n" - "'ENCRYPTED' /\n" - "'ENUM' /\n" - "'ERROR' /\n" - "'ESCAPE' /\n" - "'EVENT' /\n" - "'EXCLUDE' /\n" - "'EXCLUDING' /\n" - "'EXCLUSIVE' /\n" - "'EXECUTE' /\n" - "'EXPLAIN' /\n" - "'EXPORT' /\n" - "'EXPORT_STATE' /\n" - "'EXTENSION' /\n" - "'EXTENSIONS' /\n" - "'EXTERNAL' /\n" - "'FAMILY' /\n" - "'FILTER' /\n" - "'FIRST' /\n" - "'FOLLOWING' /\n" - "'FORCE' /\n" - "'FORWARD' /\n" - "'FUNCTION' /\n" - "'FUNCTIONS' /\n" - "'GLOBAL' /\n" - "'GRANT' /\n" - "'GRANTED' /\n" - "'GROUPS' /\n" - "'HANDLER' /\n" - "'HEADER' /\n" - "'HOLD' /\n" - "'HOUR' /\n" - "'HOURS' /\n" - "'IDENTITY' /\n" - "'IF' /\n" - "'IGNORE' /\n" - "'IMMEDIATE' /\n" - "'IMMUTABLE' /\n" - "'IMPLICIT' /\n" - "'IMPORT' /\n" - "'INCLUDE' /\n" - "'INCLUDING' /\n" - "'INCREMENT' /\n" - "'INDEX' /\n" - "'INDEXES' /\n" - "'INHERIT' /\n" - "'INHERITS' /\n" - "'INLINE' /\n" - "'INPUT' /\n" - "'INSENSITIVE' /\n" - "'INSERT' /\n" - "'INSTALL' /\n" - "'INSTEAD' /\n" - "'INVOKER' /\n" - "'JSON' /\n" - "'ISOLATION' /\n" - "'KEY' /\n" - "'LABEL' /\n" - "'LANGUAGE' /\n" - "'LARGE' /\n" - "'LAST' /\n" - "'LEAKPROOF' /\n" - "'LEVEL' /\n" - "'LISTEN' /\n" - "'LOAD' /\n" - "'LOCAL' /\n" - "'LOCATION' /\n" - "'LOCK' /\n" - "'LOCKED' /\n" - "'LOGGED' /\n" - "'MACRO' /\n" - "'MAPPING' /\n" - "'MATCH' /\n" - "'MATCHED' /\n" - "'MATERIALIZED' /\n" - "'MAXVALUE' /\n" - "'MERGE' /\n" - "'METHOD' /\n" - "'MICROSECOND' /\n" - "'MICROSECONDS' /\n" - "'MILLENNIUM' /\n" - "'MILLENNIA' /\n" - "'MILLISECOND' /\n" - "'MILLISECONDS' /\n" - "'MINUTE' /\n" - "'MINUTES' /\n" - "'MINVALUE' /\n" - "'MODE' /\n" - "'MONTH' /\n" - "'MONTHS' /\n" - "'MOVE' /\n" - "'NAME' /\n" - "'NAMES' /\n" - "'NEW' /\n" - "'NEXT' /\n" - "'NO' /\n" - "'NOTHING' /\n" - "'NOTIFY' /\n" - "'NOWAIT' /\n" - "'NULLS' /\n" - "'OBJECT' /\n" - "'OF' /\n" - "'OFF' /\n" - "'OIDS' /\n" - "'OLD' /\n" - "'OPERATOR' /\n" - "'OPTION' /\n" - "'OPTIONS' /\n" - "'ORDINALITY' /\n" - "'OTHERS' /\n" - "'OVER' /\n" - "'OVERRIDING' /\n" - "'OWNED' /\n" - "'OWNER' /\n" - "'PARALLEL' /\n" - "'PARSER' /\n" - "'PARTIAL' /\n" - "'PARTITION' /\n" - "'PARTITIONED' /\n" - "'PASSING' /\n" - "'PASSWORD' /\n" - "'PERCENT' /\n" - "'PERSISTENT' /\n" - "'PLANS' /\n" - "'POLICY' /\n" - "'PRAGMA' /\n" - "'PRECEDING' /\n" - "'PREPARE' /\n" - "'PREPARED' /\n" - "'PRESERVE' /\n" - "'PRIOR' /\n" - "'PRIVILEGES' /\n" - "'PROCEDURAL' /\n" - "'PROCEDURE' /\n" - "'PROGRAM' /\n" - "'PUBLICATION' /\n" - "'QUARTER' /\n" - "'QUARTERS' /\n" - "'QUOTE' /\n" - "'RANGE' /\n" - "'READ' /\n" - "'REASSIGN' /\n" - "'RECHECK' /\n" - "'RECURSIVE' /\n" - "'REF' /\n" - "'REFERENCING' /\n" - "'REFRESH' /\n" - "'REINDEX' /\n" - "'RELATIVE' /\n" - "'RELEASE' /\n" - "'RENAME' /\n" - "'REPEATABLE' /\n" - "'REPLACE' /\n" - "'REPLICA' /\n" - "'RESET' /\n" - "'RESPECT' /\n" - "'RESTART' /\n" - "'RESTRICT' /\n" - "'RETURNS' /\n" - "'REVOKE' /\n" - "'ROLE' /\n" - "'ROLLBACK' /\n" - "'ROLLUP' /\n" - "'ROWS' /\n" - "'RULE' /\n" - "'SAMPLE' /\n" - "'SAVEPOINT' /\n" - "'SCHEMA' /\n" - "'SCHEMAS' /\n" - "'SCOPE' /\n" - "'SCROLL' /\n" - "'SEARCH' /\n" - "'SECRET' /\n" - "'SECOND' /\n" - "'SECONDS' /\n" - "'SECURITY' /\n" - "'SEQUENCE' /\n" - "'SEQUENCES' /\n" - "'SERIALIZABLE' /\n" - "'SERVER' /\n" - "'SESSION' /\n" - "'SET' /\n" - "'SETS' /\n" - "'SHARE' /\n" - "'SIMPLE' /\n" - "'SKIP' /\n" - "'SNAPSHOT' /\n" - "'SORTED' /\n" - "'SOURCE' /\n" - "'SQL' /\n" - "'STABLE' /\n" - "'STANDALONE' /\n" - "'START' /\n" - "'STATEMENT' /\n" - "'STATISTICS' /\n" - "'STDIN' /\n" - "'STDOUT' /\n" - "'STORAGE' /\n" - "'STORED' /\n" - "'STRICT' /\n" - "'STRIP' /\n" - "'SUBSCRIPTION' /\n" - "'SYSID' /\n" - "'SYSTEM' /\n" - "'TABLES' /\n" - "'TABLESPACE' /\n" - "'TARGET' /\n" - "'TEMP' /\n" - "'TEMPLATE' /\n" - "'TEMPORARY' /\n" - "'TEXT' /\n" - "'TIES' /\n" - "'TRANSACTION' /\n" - "'TRANSFORM' /\n" - "'TRIGGER' /\n" - "'TRUNCATE' /\n" - "'TRUSTED' /\n" - "'TYPE' /\n" - "'TYPES' /\n" - "'UNBOUNDED' /\n" - "'UNCOMMITTED' /\n" - "'UNENCRYPTED' /\n" - "'UNKNOWN' /\n" - "'UNLISTEN' /\n" - "'UNLOGGED' /\n" - "'UNTIL' /\n" - "'UPDATE' /\n" - "'USE' /\n" - "'USER' /\n" - "'VACUUM' /\n" - "'VALID' /\n" - "'VALIDATE' /\n" - "'VALIDATOR' /\n" - "'VALUE' /\n" - "'VARIABLE' /\n" - "'VARYING' /\n" - "'VERSION' /\n" - "'VIEW' /\n" - "'VIEWS' /\n" - "'VIRTUAL' /\n" - "'VOLATILE' /\n" - "'WEEK' /\n" - "'WEEKS' /\n" - "'WHITESPACE' /\n" - "'WITHIN' /\n" - "'WITHOUT' /\n" - "'WORK' /\n" - "'WRAPPER' /\n" - "'WRITE' /\n" - "'XML' /\n" - "'YEAR' /\n" - "'YEARS' /\n" - "'YES' /\n" - "'ZONE'\n" - "ReservedKeyword <- 'ALL' /\n" - "'ANALYSE' /\n" - "'ANALYZE' /\n" - "'AND' /\n" - "'ANY' /\n" - "'ARRAY' /\n" - "'AS' /\n" - "'ASC' /\n" - "'ASYMMETRIC' /\n" - "'BOTH' /\n" - "'CASE' /\n" - "'CAST' /\n" - "'CHECK' /\n" - "'COLLATE' /\n" - "'COLUMN' /\n" - "'CONSTRAINT' /\n" - "'CREATE' /\n" - "'DEFAULT' /\n" - "'DEFERRABLE' /\n" - "'DESC' /\n" - "'DESCRIBE' /\n" - "'DISTINCT' /\n" - "'DO' /\n" - "'ELSE' /\n" - "'END' /\n" - "'EXCEPT' /\n" - "'FALSE' /\n" - "'FETCH' /\n" - "'FOR' /\n" - "'FOREIGN' /\n" - "'FROM' /\n" - "'GROUP' /\n" - "'HAVING' /\n" - "'QUALIFY' /\n" - "'IN' /\n" - "'INITIALLY' /\n" - "'INTERSECT' /\n" - "'INTO' /\n" - "'LAMBDA' /\n" - "'LATERAL' /\n" - "'LEADING' /\n" - "'LIMIT' /\n" - "'NOT' /\n" - "'NULL' /\n" - "'OFFSET' /\n" - "'ON' /\n" - "'ONLY' /\n" - "'OR' /\n" - "'ORDER' /\n" - "'PIVOT' /\n" - "'PIVOT_WIDER' /\n" - "'PIVOT_LONGER' /\n" - "'PLACING' /\n" - "'PRIMARY' /\n" - "'REFERENCES' /\n" - "'RETURNING' /\n" - "'SELECT' /\n" - "'SHOW' /\n" - "'SOME' /\n" - "'SUMMARIZE' /\n" - "'SYMMETRIC' /\n" - "'TABLE' /\n" - "'THEN' /\n" - "'TO' /\n" - "'TRAILING' /\n" - "'TRUE' /\n" - "'UNION' /\n" - "'UNIQUE' /\n" - "'UNPIVOT' /\n" - "'USING' /\n" - "'VARIADIC' /\n" - "'WHEN' /\n" - "'WHERE' /\n" - "'WINDOW' /\n" - "'WITH'\n" - "ColumnNameKeyword <- 'BETWEEN' /\n" - "'BIGINT' /\n" - "'BIT' /\n" - "'BOOLEAN' /\n" - "'CHAR' /\n" - "'CHARACTER' /\n" - "'COALESCE' /\n" - "'COLUMNS' /\n" - "'DEC' /\n" - "'DECIMAL' /\n" - "'EXISTS' /\n" - "'EXTRACT' /\n" - "'FLOAT' /\n" - "'GENERATED' /\n" - "'GROUPING' /\n" - "'GROUPING_ID' /\n" - "'INOUT' /\n" - "'INT' /\n" - "'INTEGER' /\n" - "'INTERVAL' /\n" - "'MAP' /\n" - "'NATIONAL' /\n" - "'NCHAR' /\n" - "'NONE' /\n" - "'NULLIF' /\n" - "'NUMERIC' /\n" - "'OUT' /\n" - "'OVERLAY' /\n" - "'POSITION' /\n" - "'PRECISION' /\n" - "'REAL' /\n" - "'ROW' /\n" - "'SETOF' /\n" - "'SMALLINT' /\n" - "'SUBSTRING' /\n" - "'STRUCT' /\n" - "'TIME' /\n" - "'TIMESTAMP' /\n" - "'TREAT' /\n" - "'TRIM' /\n" - "'TRY_CAST' /\n" - "'VALUES' /\n" - "'VARCHAR' /\n" - "'XMLATTRIBUTES' /\n" - "'XMLCONCAT' /\n" - "'XMLELEMENT' /\n" - "'XMLEXISTS' /\n" - "'XMLFOREST' /\n" - "'XMLNAMESPACES' /\n" - "'XMLPARSE' /\n" - "'XMLPI' /\n" - "'XMLROOT' /\n" - "'XMLSERIALIZE' /\n" - "'XMLTABLE'\n" - "FuncNameKeyword <- 'ASOF' /\n" - "'AT' /\n" - "'AUTHORIZATION' /\n" - "'BINARY' /\n" - "'COLLATION' /\n" - "'CONCURRENTLY' /\n" - "'CROSS' /\n" - "'FREEZE' /\n" - "'FULL' /\n" - "'GENERATED' /\n" - "'GLOB' /\n" - "'ILIKE' /\n" - "'INNER' /\n" - "'IS' /\n" - "'ISNULL' /\n" - "'JOIN' /\n" - "'LEFT' /\n" - "'LIKE' /\n" - "'MAP' /\n" - "'NATURAL' /\n" - "'NOTNULL' /\n" - "'OUTER' /\n" - "'OVERLAPS' /\n" - "'POSITIONAL' /\n" - "'RIGHT' /\n" - "'SIMILAR' /\n" - "'STRUCT' /\n" - "'TABLESAMPLE' /\n" - "'VERBOSE'\n" - "TypeNameKeyword <- 'ASOF' /\n" - "'AT' /\n" - "'AUTHORIZATION' /\n" - "'BINARY' /\n" - "'BY' /\n" - "'COLLATION' /\n" - "'COLUMNS' /\n" - "'CONCURRENTLY' /\n" - "'CROSS' /\n" - "'FREEZE' /\n" - "'FULL' /\n" - "'GLOB' /\n" - "'ILIKE' /\n" - "'INNER' /\n" - "'IS' /\n" - "'ISNULL' /\n" - "'JOIN' /\n" - "'LEFT' /\n" - "'LIKE' /\n" - "'NATURAL' /\n" - "'NOTNULL' /\n" - "'OUTER' /\n" - "'OVERLAPS' /\n" - "'POSITIONAL' /\n" - "'RIGHT' /\n" - "'UNPACK' /\n" - "'SIMILAR' /\n" - "'TABLESAMPLE' /\n" - "'TRY_CAST' /\n" - "'VERBOSE' /\n" - "'SEMI' /\n" - "'ANTI'\n" - "PivotStatement <- PivotKeyword TableRef PivotOn? PivotUsing? PivotGroupByList?\n" - "PivotOn <- 'ON' PivotColumnList\n" - "PivotUsing <- 'USING' TargetList\n" - "PivotColumnList <- List(PivotColumnEntry)\n" - "PivotColumnEntry <- PivotColumnSubquery / PivotValueList / PivotColumnExpression\n" - "PivotColumnExpression <- Expression\n" - "PivotColumnSubquery <- BaseExpression 'IN' Parens(SelectStatementInternal)\n" - "PivotKeyword <- 'PIVOT' / 'PIVOT_WIDER'\n" - "UnpivotKeyword <- 'UNPIVOT' / 'PIVOT_LONGER'\n" - "UnpivotStatement <- UnpivotKeyword TableRef 'ON' TargetList IntoNameValues?\n" - "IntoNameValues <- 'INTO' 'NAME' ColIdOrString ValueOrValues List(Identifier)\n" - "ValueOrValues <- 'VALUE' / 'VALUES'\n" - "IncludeOrExcludeNulls <- IncludeNulls / ExcludeNulls\n" - "IncludeNulls <- 'INCLUDE' 'NULLS'\n" - "ExcludeNulls <- 'EXCLUDE' 'NULLS'\n" - "UnpivotHeader <- UnpivotHeaderSingle / UnpivotHeaderList\n" - "UnpivotHeaderSingle <- ColIdOrString\n" - "UnpivotHeaderList <- Parens(List(ColIdOrString))\n" - "ColumnReference <- CatalogReservedSchemaTableColumnName / SchemaReservedTableColumnName / TableReservedColumnName " - "/ NestedColumnName\n" - "CatalogReservedSchemaTableColumnName <- CatalogQualification ReservedSchemaQualification " - "ReservedTableQualification ReservedColumnName\n" - "SchemaReservedTableColumnName <- SchemaQualification ReservedTableQualification ReservedColumnName\n" - "TableReservedColumnName <- TableQualification ReservedColumnName\n" - "FunctionExpression <- FunctionIdentifier Parens(DistinctOrAll? List(FunctionArgument)? OrderByClause? " - "IgnoreOrRespectNulls?) WithinGroupClause? FilterClause? ExportClause? OverClause?\n" - "FunctionIdentifier <- CatalogReservedSchemaFunctionName / SchemaReservedFunctionName / FunctionName\n" - "CatalogReservedSchemaFunctionName <- CatalogQualification ReservedSchemaQualification? ReservedFunctionName\n" - "SchemaReservedFunctionName <- SchemaQualification ReservedFunctionName\n" - "DistinctOrAll <- 'DISTINCT' / 'ALL'\n" - "ExportClause <- 'EXPORT_STATE'\n" - "WithinGroupClause <- 'WITHIN' 'GROUP' Parens(OrderByClause)\n" - "FilterClause <- 'FILTER' Parens('WHERE'? Expression)\n" - "IgnoreOrRespectNulls <- IgnoreNulls / RespectNulls\n" - "IgnoreNulls <- 'IGNORE' 'NULLS'\n" - "RespectNulls <- 'RESPECT' 'NULLS'\n" - "ParenthesisExpression <- Parens(List(Expression))\n" - "LiteralExpression <- StringLiteral / NumberLiteral / ConstantLiteral\n" - "ConstantLiteral <- NullLiteral / TrueLiteral / FalseLiteral\n" - "NullLiteral <- 'NULL'\n" - "TrueLiteral <- 'TRUE'\n" - "FalseLiteral <- 'FALSE'\n" - "CastExpression <- CastOrTryCast Parens(Expression 'AS' Type)\n" - "CastOrTryCast <- 'CAST' / 'TRY_CAST'\n" - "ColIdDot <- ColId '.'\n" - "StarExpression <- ColIdDot* '*' ExcludeList? ReplaceList? RenameList?\n" - "ExcludeList <- ExcludeOrExcept ExcludeNameList / ExcludeNameSingle\n" - "ExcludeOrExcept <- 'EXCLUDE' / 'EXCEPT'\n" - "ExcludeNameList <- Parens(List(ExcludeName))\n" - "ExcludeNameSingle <- ExcludeName\n" - "ExcludeName <- DottedIdentifier / ColIdOrString\n" - "ReplaceList <- 'REPLACE' ReplaceEntries\n" - "ReplaceEntries <- ReplaceEntrySingle / ReplaceEntryList\n" - "ReplaceEntrySingle <- ReplaceEntry\n" - "ReplaceEntryList <- Parens(List(ReplaceEntry))\n" - "ReplaceEntry <- Expression 'AS' ColumnReference\n" - "RenameList <- 'RENAME' (RenameEntryList / SingleRenameEntry)\n" - "RenameEntryList <- Parens(List(RenameEntry))\n" - "SingleRenameEntry <- RenameEntry\n" - "RenameEntry <- ExcludeName 'AS' Identifier\n" - "SubqueryExpression <- 'NOT'? 'EXISTS'? SubqueryReference\n" - "CaseExpression <- 'CASE' Expression? CaseWhenThen+ CaseElse? 'END'\n" - "CaseWhenThen <- 'WHEN' Expression 'THEN' Expression\n" - "CaseElse <- 'ELSE' Expression\n" - "TypeLiteral <- ColId StringLiteral\n" - "IntervalLiteral <- 'INTERVAL' IntervalParameter Interval?\n" - "IntervalParameter <- StringLiteral / NumberLiteral / ParensExpression\n" - "FrameClause <- Framing FrameExtent WindowExcludeClause?\n" - "Framing <- 'ROWS' / 'RANGE' / 'GROUPS'\n" - "FrameExtent <- BetweenFrameExtent / SingleFrameExtent\n" - "SingleFrameExtent <- FrameBound\n" - "BetweenFrameExtent <- 'BETWEEN' FrameBound 'AND' FrameBound\n" - "FrameBound <- FrameUnbounded / FrameCurrentRow / FrameExpression\n" - "FrameUnbounded <- 'UNBOUNDED' PrecedingOrFollowing\n" - "FrameExpression <- Expression PrecedingOrFollowing\n" - "FrameCurrentRow <- 'CURRENT' 'ROW'\n" - "PrecedingOrFollowing <- 'PRECEDING' / 'FOLLOWING'\n" - "WindowExcludeClause <- 'EXCLUDE' WindowExcludeElement\n" - "WindowExcludeElement <- ExcludeCurrentRow / ExcludeGroup / ExcludeTies / ExcludeNoOthers\n" - "ExcludeCurrentRow <- 'CURRENT' 'ROW'\n" - "ExcludeGroup <- 'GROUP'\n" - "ExcludeTies <- 'TIES'\n" - "ExcludeNoOthers <- 'NO' 'OTHERS'\n" - "OverClause <- 'OVER' WindowFrame\n" - "WindowFrame <- ParensIdentifier / WindowFrameDefinition / Identifier\n" - "ParensIdentifier <- Parens(Identifier)\n" - "WindowFrameDefinition <- WindowFrameNameContentsParens / WindowFrameContentsParens\n" - "WindowFrameNameContentsParens <- Parens(BaseWindowName? WindowFrameContents)\n" - "WindowFrameContentsParens <- Parens(WindowFrameContents)\n" - "WindowFrameContents <- WindowPartition? OrderByClause? FrameClause?\n" - "BaseWindowName <- Identifier\n" - "WindowPartition <- 'PARTITION' 'BY' List(Expression)\n" - "ListExpression <- ArrayBoundedListExpression / ArrayParensSelect\n" - "ArrayBoundedListExpression <- 'ARRAY'? BoundedListExpression\n" - "ArrayParensSelect <- 'ARRAY' Parens(SelectStatementInternal)\n" - "BoundedListExpression <- '[' List(Expression)? ']'\n" - "StructExpression <- '{' List(StructField) '}'\n" - "StructField <- ColIdOrString ':' Expression\n" - "MapExpression <- 'MAP' MapStructExpression\n" - "MapStructExpression <- '{' List(MapStructField)? '}'\n" - "MapStructField <- Expression ':' Expression\n" - "GroupingExpression <- GroupingOrGroupingId Parens(List(Expression)?)\n" - "GroupingOrGroupingId <- 'GROUPING' / 'GROUPING_ID'\n" - "Parameter <- QuestionMarkNumberedParameter / AnonymousParameter / NumberedParameter / ColLabelParameter\n" - "QuestionMarkNumberedParameter <- '?' NumberLiteral\n" - "AnonymousParameter <- '?'\n" - "NumberedParameter <- '$' NumberLiteral\n" - "ColLabelParameter <- '$' ColLabel\n" - "PositionalExpression <- '#' NumberLiteral\n" - "DefaultExpression <- 'DEFAULT'\n" - "ListComprehensionExpression <- '[' Expression 'FOR' List(ColIdOrString) 'IN' Expression ListComprehensionFilter? " - "']'\n" - "ListComprehensionFilter <- 'IF' Expression\n" - "ParensExpression <- Parens(Expression)\n" - "SingleExpression <-\n" - " ParensExpression /\n" - " LiteralExpression /\n" - " Parameter /\n" - " SubqueryExpression /\n" - " SpecialFunctionExpression /\n" - " ParenthesisExpression /\n" - " IntervalLiteral /\n" - " TypeLiteral /\n" - " CaseExpression /\n" - " StarExpression /\n" - " CastExpression /\n" - " GroupingExpression /\n" - " MapExpression /\n" - " FunctionExpression /\n" - " ColumnReference /\n" - " ListComprehensionExpression /\n" - " ListExpression /\n" - " StructExpression /\n" - " PositionalExpression /\n" - " DefaultExpression\n" - "# LEVEL 1 (Lowest)\n" - "Expression <- LambdaArrowExpression\n" - "ColumnDefaultExpr <- ColDefOrExpr\n" - "# LEVEL 1.5\n" - "LambdaArrowExpression <- LogicalOrExpression SingleArrowPair*\n" - "SingleArrowPair <- '->' LogicalOrExpression\n" - "LogicalOrExpression <- LogicalAndExpression ('OR' LogicalAndExpression)*\n" - "ColDefOrExpr <- ColDefAndExpr ('OR' ColDefAndExpr)*\n" - "# LEVEL 2\n" - "LogicalAndExpression <- LogicalNotExpression ('AND' LogicalNotExpression)*\n" - "ColDefAndExpr <- IsDistinctFromExpression ('AND' IsDistinctFromExpression)*\n" - "# LEVEL 3\n" - "LogicalNotExpression <- 'NOT'* IsExpression\n" - "# LEVEL 4\n" - "IsExpression <- IsDistinctFromExpression IsTest*\n" - "IsTest <- IsLiteral / NotNull / IsNull\n" - "IsLiteral <- 'IS' 'NOT'? (TrueLiteral / FalseLiteral / NullLiteral / UnknownLiteral)\n" - "UnknownLiteral <- 'UNKNOWN'\n" - "NotNull <- ('NOT' 'NULL') / 'NOTNULL'\n" - "IsNull <- 'ISNULL'\n" - "# LEVEL 5 (Split because IsDistinctFromExpression allows post expression while IsOperator does not)\n" - "IsDistinctFromExpression <- ComparisonExpression (IsDistinctFromOp ComparisonExpression)*\n" - "IsDistinctFromOp <- 'IS' 'NOT'? 'DISTINCT' 'FROM'\n" - "# LEVEL 6\n" - "ComparisonExpression <- BetweenInLikeExpression (ComparisonOperator 'NOT'* BetweenInLikeExpression)*\n" - "ComparisonOperator <-\n" - " OperatorEqual /\n" - " OperatorNotEqual /\n" - " OperatorLessThan /\n" - " OperatorGreaterThan /\n" - " OperatorLessThanEquals /\n" - " OperatorGreaterThanEquals\n" - "OperatorEqual <- '=' / '=='\n" - "OperatorNotEqual <- '!=' / '<>'\n" - "OperatorLessThan <- '<'\n" - "OperatorGreaterThan <- '>'\n" - "OperatorLessThanEquals <- '<='\n" - "OperatorGreaterThanEquals <- '>='\n" - "# LEVEL 7\n" - "BetweenInLikeExpression <- OtherOperatorExpression BetweenInLikeOp?\n" - "BetweenInLikeOp <- 'NOT'? (BetweenClause / InClause / LikeClause)\n" - "LikeClause <- LikeVariations OtherOperatorExpression EscapeClause?\n" - "EscapeClause <- 'ESCAPE' ComparisonExpression\n" - "LikeVariations <- SimilarToToken / ILikeToken / LikeToken / GlobToken / NotILikeOp / NotLikeOp / NotSimilarToOp\n" - "LikeToken <- 'LIKE' / '~~'\n" - "ILikeToken <- 'ILIKE' / '~~*'\n" - "GlobToken <- 'GLOB' / '~~~'\n" - "SimilarToToken <- ('SIMILAR' 'TO') / '~'\n" - "NotILikeOp <- '!~~*'\n" - "NotLikeOp <- '!~~'\n" - "NotSimilarToOp <- '!~'\n" - "InClause <- 'IN' InExpression\n" - "InExpression <- InExpressionList / InSelectStatement / OtherOperatorExpression\n" - "InExpressionList <- Parens(List(Expression))\n" - "InSelectStatement <- Parens(SelectStatementInternal)\n" - "BetweenClause <- 'BETWEEN' OtherOperatorExpression 'AND' OtherOperatorExpression\n" - "# LEVEL 8\n" - "OtherOperatorExpression <- BitwiseExpression (OtherOperator BitwiseExpression)*\n" - "OtherOperator <-\n" - " QualifiedOperator / AnyAllOperator / InetOperator / JsonOperator / ListOperator / StringOperator / " - "OperatorLiteral\n" - "OperatorLiteral <- Identifier\n" - "AnyAllOperator <- AnyOp AnyOrAll\n" - "AnyOrAll <- SubqueryAny / SubqueryAll\n" - "SubqueryAny <- 'ANY'\n" - "SubqueryAll <- 'ALL'\n" - "InetOperator <- '>>=' / '<<='\n" - "JsonOperator <- '->>'\n" - "ListOperator <- '&&' / '@>' / '<@'\n" - "StringOperator <- '^@' / '||'\n" - "QualifiedOperator <- 'OPERATOR' Parens(ColIdDot* AnyOp)\n" - "AnyOp <- '!~~*' / '>>=' / '<<=' / '->>' / '!~~' / '~~*' / '~~~' / '!~' / '^@' / '||' / '&&' / '@>' / '<@' / '<=' " - "/ '>=' / '<>' / '!=' / '==' / '<<' / '>>' / '//' / '**' / '->' / '~~' / '+' / '-' / '*' / '/' / '%' / '^' / '<' / " - "'>' / '=' / '&' / '|' / '~' / '!'\n" - "# LEVEL 9\n" - "BitwiseExpression <- AdditiveExpression (BitOperator AdditiveExpression)*\n" - "BitOperator <- '&' / '|' / '<<' / '>>'\n" - "# LEVEL 10\n" - "AdditiveExpression <- MultiplicativeExpression (Term MultiplicativeExpression)*\n" - "Term <- '+' / '-'\n" - "# LEVEL 11\n" - "MultiplicativeExpression <- ExponentiationExpression (Factor ExponentiationExpression)*\n" - "Factor <- '*' / '/' / '//' / '%'\n" - "# LEVEL 12\n" - "ExponentiationExpression <- CollateExpression (ExponentOperator CollateExpression)*\n" - "ExponentOperator <- '^' / '**'\n" - "# LEVEL 13\n" - "CollateExpression <- AtTimeZoneExpression (CollateOperator AtTimeZoneExpression)*\n" - "CollateOperator <- 'COLLATE'\n" - "# LEVEL 14\n" - "AtTimeZoneExpression <- PrefixExpression (AtTimeZoneOperator PrefixExpression)*\n" - "AtTimeZoneOperator <- 'AT' 'TIME' 'ZONE'\n" - "# LEVEL 15\n" - "PrefixExpression <- PrefixOperator* BaseExpression\n" - "PrefixOperator <- QualifiedOperator / MinusPrefixOperator / PlusPrefixOperator / TildePrefixOperator\n" - "MinusPrefixOperator <- '-'\n" - "PlusPrefixOperator <- '+'\n" - "TildePrefixOperator <- '~'\n" - "# LEVEL 16 (Highest)\n" - "BaseExpression <- SingleExpression Indirection*\n" - "Indirection <- CastOperator / DotOperator / SliceExpression / PostfixOperator\n" - "CastOperator <- '::' Type\n" - "DotOperator <- '.' (MethodExpression / ColLabel)\n" - "MethodExpression <- ColLabel Parens(DistinctOrAll? List(FunctionArgument)? OrderByClause? IgnoreOrRespectNulls?)\n" - "SliceExpression <- '[' SliceBound ']'\n" - "SliceBound <- Expression? EndSliceBound? StepSliceBound?\n" - "EndSliceBound <- ':' (Expression / '-')?\n" - "StepSliceBound <- ':' Expression?\n" - "PostfixOperator <- '!'\n" - "SpecialFunctionExpression <- CoalesceExpression / UnpackExpression / TryExpression / ColumnsExpression / " - "ExtractExpression / LambdaExpression / NullIfExpression / PositionExpression / RowExpression / " - "SubstringExpression / TrimExpression / OverlayExpression\n" - "CoalesceExpression <- 'COALESCE' Parens(List(Expression))\n" - "UnpackExpression <- 'UNPACK' Parens(Expression)\n" - "TryExpression <- 'TRY' Parens(Expression)\n" - "ColumnsExpression <- '*'? 'COLUMNS' Parens(Expression)\n" - "ExtractExpression <- 'EXTRACT' Parens(ExtractArgument 'FROM' Expression)\n" - "LambdaExpression <- 'LAMBDA' List(ColIdOrString) ':' Expression\n" - "NullIfExpression <- 'NULLIF' Parens(Expression ',' Expression)\n" - "PositionExpression <- 'POSITION' Parens(SingleExpression 'IN' SingleExpression)\n" - "RowExpression <- 'ROW' Parens(List(Expression)?)\n" - "SubstringExpression <- 'SUBSTRING' Parens(SubstringArguments)\n" - "SubstringArguments <- SubstringParameters / SubstringExpressionList\n" - "SubstringExpressionList <- List(Expression)\n" - "SubstringParameters <- Expression SubstringFromFor\n" - "SubstringFromFor <- SubstringFromOptionalFor / SubstringFor\n" - "SubstringFromOptionalFor <- FromExpression ForExpression?\n" - "SubstringFor <- ForExpression\n" - "TrimExpression <- 'TRIM' Parens(TrimDirection? TrimSource? List(Expression))\n" - "TrimDirection <- TrimBoth / TrimLeading / TrimTrailing\n" - "TrimBoth <- 'BOTH'\n" - "TrimLeading <- 'LEADING'\n" - "TrimTrailing <- 'TRAILING'\n" - "TrimSource <- Expression? 'FROM'\n" - "OverlayExpression <- 'OVERLAY' Parens(OverlayArguments)\n" - "OverlayArguments <- OverlayParameters / OverlayExpressionList\n" - "OverlayParameters <- Expression 'PLACING' Expression FromExpression ForExpression?\n" - "FromExpression <- 'FROM' Expression\n" - "ForExpression <- 'FOR' Expression\n" - "OverlayExpressionList <- List(Expression)\n" - "ExtractArgument <-\n" - " YearKeyword / MonthKeyword / DayKeyword / HourKeyword / MinuteKeyword / SecondKeyword /\n" - " MillisecondKeyword / MicrosecondKeyword / WeekKeyword / QuarterKeyword / DecadeKeyword /\n" - " CenturyKeyword / MillenniumKeyword / Identifier / StringLiteral\n" - "ExecuteStatement <- 'EXECUTE' Identifier TableFunctionArguments?\n" - "CreateSecretStmt <- 'SECRET' IfNotExists? SecretName? SecretStorageSpecifier? GenericCopyOptionList\n" - "SecretStorageSpecifier <- 'IN' Identifier\n" - "SecretName <- ColId\n" - "CreateViewStmt <- CreateRecursive? 'VIEW' IfNotExists? QualifiedName InsertColumnList? WithList? 'AS' " - "SelectStatementInternal\n" - "CreateRecursive <- 'RECURSIVE'\n" - "DescribeStatement <- ShowTables / ShowSelect / ShowAllTables / ShowQualifiedName\n" - "ShowSelect <- ShowOrDescribeOrSummarize SelectStatementInternal\n" - "ShowAllTables <- ShowOrDescribe 'ALL' 'TABLES'\n" - "ShowQualifiedName <- ShowOrDescribeOrSummarize DescribeTarget?\n" - "ShowTables <- ShowOrDescribe 'TABLES' 'FROM' QualifiedName\n" - "DescribeTarget <- DescribeBaseTableName / DescribeStringLiteral\n" - "DescribeBaseTableName <- BaseTableName\n" - "DescribeStringLiteral <- StringLiteral\n" - "ShowOrDescribeOrSummarize <- ShowOrDescribe / Summarize\n" - "Summarize <- SummarizeRule\n" - "SummarizeRule <- 'SUMMARIZE'\n" - "ShowOrDescribe <- ShowRule / DescribeRule\n" - "ShowRule <- 'SHOW'\n" - "DescribeRule <- DescribeLongRule / DescRule\n" - "DescribeLongRule <- 'DESCRIBE'\n" - "DescRule <- 'DESC'\n" - "VacuumStatement <- 'VACUUM' VacuumOptions? AnalyzeTarget?\n" - "VacuumOptions <- VacuumParensOptions / VacuumLegacyOptions\n" - "VacuumParensOptions <- Parens(List(VacuumOption))\n" - "VacuumLegacyOptions <- OptFull? OptFreeze? OptVerbose? OptAnalyze?\n" - "VacuumOption <- OptAnalyze / OptFreeze / OptFull / OptVerbose / Identifier\n" - "OptAnalyze <- 'ANALYZE'\n" - "OptFull <- 'FULL'\n" - "OptFreeze <- 'FREEZE'\n" - "OptVerbose <- 'VERBOSE'\n" - "NameList <- Parens(List(ColId))\n" - "MergeIntoStatement <- WithClause? 'MERGE' 'INTO' TargetOptAlias MergeIntoUsingClause JoinQualifier MergeMatch+ " - "ReturningClause?\n" - "MergeIntoUsingClause <- 'USING' TableRef\n" - "MergeMatch <- MatchedClause / NotMatchedClause\n" - "MatchedClause <- 'WHEN' 'MATCHED' AndExpression? 'THEN' MatchedClauseAction\n" - "MatchedClauseAction <- UpdateMatchClause / DeleteMatchClause / InsertMatchClause / DoNothingMatchClause / " - "ErrorMatchClause\n" - "UpdateMatchClause <- 'UPDATE' UpdateMatchInfo?\n" - "UpdateMatchInfo <- UpdateMatchSetAction / UpdateByNameOrPosition\n" - "UpdateMatchSetAction <- UpdateMatchSetClause\n" - "UpdateByNameOrPosition <- ByNameOrPosition\n" - "DeleteMatchClause <- 'DELETE'\n" - "InsertMatchClause <- 'INSERT' InsertMatchInfo?\n" - "InsertMatchInfo <- InsertValuesList / InsertDefaultValues / InsertByNameOrPosition\n" - "InsertDefaultValues <- 'DEFAULT' 'VALUES'\n" - "InsertByNameOrPosition <- ByNameOrPosition? '*'?\n" - "InsertValuesList <- InsertColumnList? 'VALUES' Parens(List(Expression))\n" - "DoNothingMatchClause <- 'DO' 'NOTHING'\n" - "ErrorMatchClause <- 'ERROR' Expression?\n" - "UpdateMatchSetClause <- 'SET' UpdateMatchSetInfo\n" - "UpdateMatchSetInfo <- UpdateSetClause / StarSymbol\n" - "AndExpression <- 'AND' Expression\n" - "NotMatchedClause <- 'WHEN' 'NOT' 'MATCHED' BySourceOrTarget? AndExpression? 'THEN' MatchedClauseAction\n" - "BySourceOrTarget <- BySource / ByTarget\n" - "BySource <- 'BY' 'SOURCE'\n" - "ByTarget <- 'BY' 'TARGET'\n" - "PragmaStatement <- 'PRAGMA' PragmaAssignOrFunction\n" - "PragmaAssignOrFunction <- PragmaAssign / PragmaFunction\n" - "PragmaAssign <- SettingName '=' VariableList\n" - "PragmaFunction <- PragmaName PragmaParameters?\n" - "PragmaParameters <- Parens(List(Expression))\n" - "DeallocateStatement <- 'DEALLOCATE' DeallocatePrepare? Identifier\n" - "DeallocatePrepare <- 'PREPARE'\n" - "PrepareStatement <- 'PREPARE' Identifier TypeList? 'AS' Statement\n" - "TypeList <- Parens(List(Type))\n" - "CreateStatement <- 'CREATE' OrReplace? Temporary? CreateStatementVariation\n" - "CreateStatementVariation <- CreateTableStmt / CreateMacroStmt / CreateSequenceStmt / CreateTypeStmt / " - "CreateSchemaStmt / CreateViewStmt / CreateIndexStmt / CreateSecretStmt / CreateTriggerStmt\n" - "OrReplace <- 'OR' 'REPLACE'\n" - "Temporary <- Persistent / TempPersistent / TemporaryPersistent\n" - "Persistent <- 'PERSISTENT'\n" - "TempPersistent <- 'TEMP'\n" - "TemporaryPersistent <- 'TEMPORARY'\n" - "CreateTableStmt <- 'TABLE' IfNotExists? QualifiedName CreateTableDefinition CommitAction?\n" - "CreateTableDefinition <- CreateTableAs / CreateColumnList\n" - "CreateTableAs <- IdentifierList? PartitionSortedOptions? WithList? 'AS' Statement WithData?\n" - "PartitionSortedOptions <- PartitionOptSortedOptions / SortedOptPartitionOptions\n" - "PartitionOptSortedOptions <- PartitionOptions SortedOptions?\n" - "SortedOptPartitionOptions <- SortedOptions PartitionOptions?\n" - "PartitionOptions <- 'PARTITIONED' 'BY' Parens(List(Expression))\n" - "SortedOptions <- 'SORTED' 'BY' Parens(List(Expression))\n" - "WithData <- WithDataOnly / WithNoData\n" - "WithDataOnly <- 'WITH' 'DATA'\n" - "WithNoData <- 'WITH' 'NO' 'DATA'\n" - "IdentifierList <- Parens(List(Identifier))\n" - "CreateColumnList <- Parens(CreateTableColumnList?) PartitionSortedOptions? WithList?\n" - "IfNotExists <- 'IF' 'NOT' 'EXISTS'\n" - "QualifiedName <- CatalogReservedSchemaIdentifier / SchemaReservedIdentifierOrStringLiteral / " - "IdentifierOrStringLiteral\n" - "SchemaReservedIdentifierOrStringLiteral <- SchemaQualification ReservedIdentifierOrStringLiteral\n" - "CatalogReservedSchemaIdentifier <- CatalogQualification ReservedSchemaQualification " - "ReservedIdentifierOrStringLiteral\n" - "IdentifierOrStringLiteral <- Identifier / StringLiteral\n" - "ReservedIdentifierOrStringLiteral <- ReservedIdentifier / StringLiteral\n" - "CatalogQualification <- CatalogName '.'\n" - "SchemaQualification <- SchemaName '.'\n" - "ReservedSchemaQualification <- ReservedSchemaName '.'\n" - "TableQualification <- TableName '.'\n" - "ReservedTableQualification <- ReservedTableName '.'\n" - "CreateTableColumnList <- List(CreateTableColumnElement)\n" - "CreateTableColumnElement <- CreateTableColumnDefinition / CreateTableConstraint\n" - "CreateTableColumnDefinition <- ColumnDefinition\n" - "CreateTableConstraint <- TopLevelConstraint\n" - "ColumnDefinition <- DottedIdentifier Type? GeneratedColumn? ConstraintNameClause? ColumnConstraint*\n" - "ColumnConstraint <- NotNullConstraint / UniqueConstraint / PrimaryKeyConstraint / DefaultValue / CheckConstraint " - "/ ForeignKeyConstraint / ColumnCollation / ColumnCompression\n" - "NotNullConstraint <- NullConstraint / NotNullColumnConstraint\n" - "NullConstraint <- 'NULL'\n" - "NotNullColumnConstraint <- 'NOT' 'NULL'\n" - "UniqueConstraint <- 'UNIQUE'\n" - "PrimaryKeyConstraint <- 'PRIMARY' 'KEY'\n" - "DefaultValue <- 'DEFAULT' ColumnDefaultExpr\n" - "CheckConstraint <- 'CHECK' Parens(Expression)\n" - "ForeignKeyConstraint <- 'REFERENCES' BaseTableName Parens(ColumnList)? KeyActions\n" - "ColumnCollation <- 'COLLATE' DottedIdentifier\n" - "ColumnCompression <- 'USING' 'COMPRESSION' ColIdOrString\n" - "KeyActions <- UpdateAction? DeleteAction?\n" - "UpdateAction <- 'ON' 'UPDATE' KeyAction\n" - "DeleteAction <- 'ON' 'DELETE' KeyAction\n" - "KeyAction <- NoKeyAction / RestrictKeyAction / CascadeKeyAction / SetNullKeyAction / SetDefaultKeyAction\n" - "NoKeyAction <- 'NO' 'ACTION'\n" - "RestrictKeyAction <- 'RESTRICT'\n" - "CascadeKeyAction <- 'CASCADE'\n" - "SetNullKeyAction <- 'SET' 'NULL'\n" - "SetDefaultKeyAction <- 'SET' 'DEFAULT'\n" - "TopLevelConstraint <- ConstraintNameClause? TopLevelConstraintList\n" - "TopLevelConstraintList <- TopPrimaryKeyConstraint / CheckConstraint / TopUniqueConstraint / " - "TopForeignKeyConstraint\n" - "ConstraintNameClause <- 'CONSTRAINT' Identifier\n" - "TopPrimaryKeyConstraint <- 'PRIMARY' 'KEY' ColumnIdList\n" - "TopUniqueConstraint <- 'UNIQUE' ColumnIdList\n" - "TopForeignKeyConstraint <- 'FOREIGN' 'KEY' ColumnIdList ForeignKeyConstraint\n" - "ColumnIdList <- Parens(List(ColId))\n" - "PlainIdentifier <- !ReservedKeyword <[a-z_]i[a-z0-9_]i*>\n" - "QuotedIdentifier <- '\"' [^\"]* '\"'\n" - "DottedIdentifier <- Identifier DotColLabel*\n" - "DotColLabel <- '.' ColLabel\n" - "Identifier <- QuotedIdentifier / PlainIdentifier\n" - "ColId <- UnreservedKeyword / ColumnNameKeyword / Identifier\n" - "ColIdOrString <- ColId / StringLiteral\n" - "TypeFuncName <- UnreservedKeyword / TypeNameKeyword / FuncNameKeyword / Identifier\n" - "TypeName <- UnreservedKeyword / TypeNameKeyword / Identifier\n" - "ColLabel <- ReservedKeyword / UnreservedKeyword / ColumnNameKeyword / FuncNameKeyword / TypeNameKeyword / " - "Identifier\n" - "ColLabelOrString <- ColLabel / StringLiteral\n" - "GeneratedColumn <- Generated? 'AS' Parens(Expression) GeneratedColumnType?\n" - "Generated <- 'GENERATED' AlwaysOrByDefault?\n" - "AlwaysOrByDefault <- 'ALWAYS' / ('BY' 'DEFAULT')\n" - "GeneratedColumnType <- VirtualGeneratedColumn / StoredGeneratedColumn\n" - "CommitAction <- 'ON' 'COMMIT' PreserveOrDelete 'ROWS'\n" - "PreserveOrDelete <- PreserveRows / DeleteRows\n" - "PreserveRows <- 'PRESERVE'\n" - "DeleteRows <- 'DELETE'\n" - "VirtualGeneratedColumn <- 'VIRTUAL'\n" - "StoredGeneratedColumn <- 'STORED'\n" - "CreateIndexStmt <- UniqueIndex? 'INDEX' IfNotExists? IndexName? 'ON' BaseTableName InsertColumnList? IndexType? " - "Parens(List(IndexElement))? WithList? WhereClause?\n" - "WithList <- 'WITH' RelOptionOrOids\n" - "RelOptionOrOids <- RelOptionList / Oids\n" - "RelOptionList <- Parens(List(RelOption))\n" - "Oids <- WithOrWithoutOids 'OIDS'\n" - "WithOrWithoutOids <- WithOids / WithoutOids\n" - "WithOids <- 'WITH'\n" - "WithoutOids <- 'WITHOUT'\n" - "IndexElement <- Expression DescOrAsc? NullsFirstOrLast?\n" - "UniqueIndex <- 'UNIQUE'\n" - "IndexType <- 'USING' Identifier\n" - "RelOption <- RelOptionName RelOptionArgumentOpt?\n" - "RelOptionName <- DottedIdentifierString / StringLiteral\n" - "DottedIdentifierString <- DottedIdentifier\n" - "RelOptionArgumentOpt <- '=' DefArg\n" - "DefArg <- DefArgNull / DefArgKeyword / DefArgStringLiteral / NumberLiteral / NoneLiteral / Expression\n" - "DefArgNull <- NullLiteral\n" - "DefArgKeyword <- ReservedKeyword\n" - "DefArgStringLiteral <- StringLiteral\n" - "NoneLiteral <- 'NONE'\n" - "LoadStatement <- 'LOAD' ColIdOrString ExtensionAlias?\n" - "ExtensionAlias <- 'AS' Identifier\n" - "InstallStatement <- 'FORCE'? 'INSTALL' IdentifierOrStringLiteral FromSource? VersionNumber?\n" - "UpdateExtensionsStatement <- 'UPDATE' 'EXTENSIONS' Parens(List(Identifier))?\n" - "FromSource <- FromSourceIdentifier / FromSourceString\n" - "FromSourceIdentifier <- 'FROM' Identifier\n" - "FromSourceString <- 'FROM' StringLiteral\n" - "VersionNumber <- 'VERSION' IdentifierOrStringLiteral\n" - "DropStatement <- 'DROP' DropEntries DropBehavior?\n" - "DropEntries <-\n" - " DropTable /\n" - " DropTableFunction /\n" - " DropFunction /\n" - " DropSchema /\n" - " DropIndex /\n" - " DropSequence /\n" - " DropCollation /\n" - " DropType /\n" - " DropSecret /\n" - " DropTrigger\n" - "DropTrigger <- 'TRIGGER' IfExists? TriggerName 'ON' BaseTableName\n" - "DropTable <- TableOrView IfExists? List(BaseTableName)\n" - "DropTableFunction <- CommentMacroTable IfExists? List(TableFunctionName)\n" - "DropFunction <- FunctionTypeMacro IfExists? List(FunctionIdentifier)\n" - "DropSchema <- 'SCHEMA' IfExists? List(QualifiedSchemaName)\n" - "DropIndex <- 'INDEX' IfExists? List(QualifiedIndexName)\n" - "QualifiedIndexName <- CatalogReservedSchemaIndex / SchemaReservedIndex / QualifiedIndexNameString\n" - "QualifiedIndexNameString <- IndexName\n" - "SchemaReservedIndex <- SchemaQualification ReservedIndexName\n" - "CatalogReservedSchemaIndex <- CatalogQualification ReservedSchemaQualification ReservedIndexName\n" - "DropSequence <- 'SEQUENCE' IfExists? List(QualifiedSequenceName)\n" - "DropCollation <- 'COLLATION' IfExists? List(CollationName)\n" - "DropType <- 'TYPE' IfExists? List(QualifiedTypeName)\n" - "DropSecret <- Temporary? 'SECRET' IfExists? SecretName DropSecretStorage?\n" - "TableOrView <- CommentTable / CommentView / MaterializedViewEntry\n" - "MaterializedViewEntry <- 'MATERIALIZED' 'VIEW'\n" - "FunctionTypeMacro <- FunctionTypeMacroKeyword / FunctionTypeFunction\n" - "FunctionTypeMacroKeyword <- 'MACRO'\n" - "FunctionTypeFunction <- 'FUNCTION'\n" - "DropBehavior <- CascadeDropBehavior / RestrictDropBehavior\n" - "CascadeDropBehavior <- 'CASCADE'\n" - "RestrictDropBehavior <- 'RESTRICT'\n" - "IfExists <- 'IF' 'EXISTS'\n" - "QualifiedSchemaName <- CatalogReservedSchema / QualifiedSchemaNameString\n" - "QualifiedSchemaNameString <- SchemaName\n" - "CatalogReservedSchema <- CatalogQualification ReservedSchemaName\n" - "DropSecretStorage <- 'FROM' Identifier\n" - "UpdateStatement <- WithClause? 'UPDATE' UpdateTarget UpdateSetClause FromClause? WhereClause? ReturningClause?\n" - "UpdateTarget <- BaseTableSet / BaseTableAliasSet\n" - "BaseTableSet <- BaseTableName 'SET'\n" - "BaseTableAliasSet <- BaseTableName UpdateAlias? 'SET'\n" - "UpdateAlias <- 'AS'? ColId\n" - "UpdateSetClause <- UpdateSetElementList / UpdateSetTuple\n" - "UpdateSetTuple <- Parens(List(ColumnName)) '=' Expression\n" - "UpdateSetElementList <- List(UpdateSetElement)\n" - "UpdateSetElement <- UpdateSetColumnTarget '=' Expression\n" - "UpdateSetColumnTarget <- ColumnName DotIdentifier*\n" - "InsertStatement <- WithClause? 'INSERT' OrAction? 'INTO' InsertTarget ByNameOrPosition? InsertColumnList? " - "InsertValues OnConflictClause? ReturningClause?\n" - "OrAction <- InsertOrReplace / InsertOrIgnore\n" - "InsertOrReplace <- 'OR' 'REPLACE'\n" - "InsertOrIgnore <- 'OR' 'IGNORE'\n" - "ByNameOrPosition <- InsertByNameOrder / InsertByPositionOrder\n" - "InsertByNameOrder <- 'BY' InsertByName\n" - "InsertByPositionOrder <- 'BY' InsertByPosition\n" - "InsertByName <- 'NAME'\n" - "InsertByPosition <- 'POSITION'\n" - "InsertTarget <- BaseTableName InsertAlias?\n" - "InsertAlias <- 'AS' Identifier\n" - "ColumnList <- List(ColId)\n" - "InsertColumnList <- Parens(ColumnList)\n" - "InsertValues <- SelectInsertValues / DefaultValues\n" - "SelectInsertValues <- SelectStatementInternal\n" - "DefaultValues <- 'DEFAULT' 'VALUES'\n" - "OnConflictClause <- 'ON' 'CONFLICT' OnConflictTarget? OnConflictAction\n" - "OnConflictTarget <- OnConflictExpressionTarget / OnConflictIndexTarget\n" - "OnConflictExpressionTarget <- ColumnIdList WhereClause?\n" - "OnConflictIndexTarget <- 'ON' 'CONSTRAINT' ConstraintName\n" - "OnConflictAction <- OnConflictUpdate / OnConflictNothing\n" - "OnConflictUpdate <- 'DO' 'UPDATE' 'SET' UpdateSetClause WhereClause?\n" - "OnConflictNothing <- 'DO' 'NOTHING'\n" - "ReturningClause <- 'RETURNING' TargetList\n" - "CreateSchemaStmt <- 'SCHEMA' IfNotExists? QualifiedName\n" - "SelectStatement <- SelectStatementInternal\n" - "SelectStatementInternal <- WithClause? SelectSetOpChain ResultModifiers?\n" - "SelectSetOpChain <- IntersectChain (SetopClause IntersectChain)*\n" - "IntersectChain <- SelectAtom (SetIntersectClause SelectAtom)*\n" - "SetIntersectClause <- 'INTERSECT' DistinctOrAll?\n" - "SelectAtom <- SelectParens / SelectStatementType\n" - "SelectParens <- Parens(SelectStatementInternal)\n" - "SetopClause <- SetopType DistinctOrAll? ByName?\n" - "SetopType <- SetopUnion / SetopExcept\n" - "SetopUnion <- 'UNION'\n" - "SetopExcept <- 'EXCEPT'\n" - "ByName <- 'BY' 'NAME'\n" - "SelectStatementType <- OptionalParensSimpleSelect / ValuesClause / DescribeStatement / TableStatement / " - "PivotStatement / UnpivotStatement\n" - "ResultModifiers <- OrderByClause? LimitOffset?\n" - "LimitOffset <- LimitOffsetClause / OffsetLimitClause\n" - "LimitOffsetClause <- LimitClause OffsetClause?\n" - "OffsetLimitClause <- OffsetClause LimitClause?\n" - "TableStatement <- 'TABLE' BaseTableName\n" - "OptionalParensSimpleSelect <- SimpleSelectParens / SimpleSelect\n" - "SimpleSelectParens <- Parens(SimpleSelect)\n" - "SimpleSelect <- SelectFrom WhereClause? GroupByClause? HavingClause? WindowClause? QualifyClause? SampleClause?\n" - "SelectFrom <- SelectFromClause / FromSelectClause\n" - "SelectFromClause <- SelectClause FromClause?\n" - "FromSelectClause <- FromClause SelectClause?\n" - "WithStatement <- ColIdOrString InsertColumnList? UsingKey? 'AS' Materialized? CTEBody\n" - "CTEBody <- Parens(CTEBodyContent)\n" - "CTEBodyContent <- SelectStatementInternal / Statement\n" - "UsingKey <- 'USING' 'KEY' Parens(TargetList)\n" - "Materialized <- 'NOT'? 'MATERIALIZED'\n" - "WithClause <- 'WITH' Recursive? List(WithStatement)\n" - "Recursive <- 'RECURSIVE'\n" - "SelectClause <- 'SELECT' DistinctClause? TargetList?\n" - "TargetList <- List(AliasedExpression)\n" - "ColumnAliases <- Parens(List(ColIdOrString))\n" - "DistinctClause <- DistinctOn / DistinctAll\n" - "DistinctAll <- 'ALL'\n" - "DistinctOn <- 'DISTINCT' DistinctOnTargets?\n" - "DistinctOnTargets <- 'ON' Parens(List(Expression))\n" - "InnerTableRef <- ValuesRef / TableFunction / TableSubquery / BaseTableRef / ParensTableRef\n" - "TableRef <- InnerTableRef JoinOrPivot*\n" - "TableSubquery <- Lateral? SubqueryReference TableAlias?\n" - "BaseTableRef <- TableAliasColon? BaseTableName TableAlias? AtClause? SampleClause?\n" - "TableAliasColon <- ColIdOrString ':'\n" - "ValuesRef <- ValuesClause TableAlias?\n" - "ParensTableRef <- TableAliasColon? Parens(TableRef) TableAlias? SampleClause?\n" - "JoinOrPivot <- JoinClause / TablePivotClause / TableUnpivotClause\n" - "TablePivotClause <- 'PIVOT' Parens(TargetList 'FOR' PivotValueList+ PivotGroupByList?) TableAlias?\n" - "PivotGroupByList <- 'GROUP' 'BY' List(ColIdOrString)\n" - "TableUnpivotClause <- 'UNPIVOT' IncludeOrExcludeNulls? Parens(UnpivotHeader 'FOR' UnpivotValueList+) TableAlias?\n" - "PivotHeader <- BaseExpression\n" - "PivotValueList <- PivotHeader 'IN' (Identifier / PivotTargetList)\n" - "UnpivotValueList <- UnpivotHeader 'IN' UnpivotTargetList\n" - "PivotTargetList <- Parens(TargetList)\n" - "UnpivotTargetList <- Parens(TargetList)\n" - "Lateral <- 'LATERAL'\n" - "BaseTableName <- CatalogReservedSchemaTable / SchemaReservedTable / TableName\n" - "SchemaReservedTable <- SchemaQualification ReservedTableName\n" - "CatalogReservedSchemaTable <- CatalogQualification ReservedSchemaQualification ReservedTableName\n" - "TableFunction <- TableFunctionLateralOpt / TableFunctionAliasColon\n" - "TableFunctionLateralOpt <- Lateral? QualifiedTableFunction TableFunctionArguments WithOrdinality? TableAlias?\n" - "TableFunctionAliasColon <- TableAliasColon QualifiedTableFunction TableFunctionArguments WithOrdinality? " - "SampleClause?\n" - "WithOrdinality <- 'WITH' 'ORDINALITY'\n" - "QualifiedTableFunction <- CatalogQualification? SchemaQualification? TableFunctionName\n" - "TableFunctionArguments <- Parens(List(FunctionArgument)?)\n" - "FunctionArgument <- NamedParameter / Expression\n" - "NamedParameter <- TypeFuncName Type? NamedParameterAssignment Expression\n" - "NamedParameterAssignment <- ':=' / '=>'\n" - "TableAlias <- TableAliasAs / TableAliasWithoutAs\n" - "TableAliasAs <- 'AS' IdentifierOrStringLiteral ColumnAliases?\n" - "TableAliasWithoutAs <- Identifier ColumnAliases?\n" - "AtClause <- 'AT' Parens(AtSpecifier)\n" - "AtSpecifier <- AtUnit '=>' Expression\n" - "AtUnit <- 'VERSION' / 'TIMESTAMP'\n" - "JoinClause <- RegularJoinClause / JoinWithoutOnClause\n" - "RegularJoinClause <- 'ASOF'? JoinType? 'JOIN' TableRef JoinQualifier\n" - "JoinWithoutOnClause <- JoinPrefix 'JOIN' TableRef\n" - "JoinQualifier <- OnClause / UsingClause\n" - "OnClause <- 'ON' Expression\n" - "UsingClause <- 'USING' Parens(List(ColumnName))\n" - "JoinType <- FullJoin / LeftJoin / RightJoin / SemiJoin / AntiJoin / InnerJoin\n" - "JoinPrefix <- CrossJoinPrefix / NaturalJoinPrefix / PositionalJoinPrefix\n" - "CrossJoinPrefix <- 'CROSS'\n" - "NaturalJoinPrefix <- 'NATURAL' JoinType?\n" - "PositionalJoinPrefix <- 'POSITIONAL'\n" - "FullJoin <- 'FULL' 'OUTER'?\n" - "LeftJoin <- 'LEFT' 'OUTER'?\n" - "RightJoin <- 'RIGHT' 'OUTER'?\n" - "SemiJoin <- 'SEMI'\n" - "AntiJoin <- 'ANTI'\n" - "InnerJoin <- 'INNER'\n" - "FromClause <- 'FROM' List(TableRef)\n" - "WhereClause <- 'WHERE' Expression\n" - "GroupByClause <- 'GROUP' 'BY' GroupByExpressions\n" - "HavingClause <- 'HAVING' Expression\n" - "QualifyClause <- 'QUALIFY' Expression\n" - "SampleClause <- (TableSample / UsingSample) SampleEntry\n" - "UsingSample <- 'USING' 'SAMPLE'\n" - "TableSample <- 'TABLESAMPLE'\n" - "WindowClause <- 'WINDOW' List(WindowDefinition)\n" - "WindowDefinition <- Identifier 'AS' WindowFrameDefinition\n" - "SampleEntry <- SampleEntryFunction / SampleEntryCount\n" - "SampleEntryCount <- SampleCount Parens(SampleProperties)?\n" - "SampleEntryFunction <- SampleFunction? Parens(SampleCount) RepeatableSample?\n" - "SampleFunction <- ColId\n" - "SampleProperties <- ColId (',' SampleSeed)?\n" - "RepeatableSample <- 'REPEATABLE' Parens(SampleSeed)\n" - "SampleSeed <- NumberLiteral\n" - "SampleCount <- SampleValue SampleUnit?\n" - "SampleValue <- NumberLiteral / Parameter\n" - "SampleUnit <- SamplePercentage / SampleRows\n" - "SamplePercentage <- '%' / 'PERCENT'\n" - "SampleRows <- 'ROWS'\n" - "GroupByExpressions <- GroupByList / GroupByAll\n" - "GroupByAll <- 'ALL'\n" - "GroupByList <- List(GroupByExpression)\n" - "GroupByExpression <- EmptyGroupingItem / CubeOrRollupClause / GroupingSetsClause / Expression\n" - "EmptyGroupingItem <- '(' ')'\n" - "CubeOrRollupClause <- CubeOrRollup Parens(List(Expression)?)\n" - "CubeOrRollup <- 'CUBE' / 'ROLLUP'\n" - "GroupingSetsClause <- 'GROUPING' 'SETS' Parens(GroupByList)\n" - "SubqueryReference <- Parens(SelectStatementInternal)\n" - "OrderByExpression <- Expression DescOrAsc? NullsFirstOrLast?\n" - "DescOrAsc <- DescendingOrder / AscendingOrder\n" - "DescendingOrder <- 'DESC' / 'DESCENDING'\n" - "AscendingOrder <- 'ASC' / 'ASCENDING'\n" - "NullsFirstOrLast <- NullsFirst / NullsLast\n" - "NullsFirst <- 'NULLS' 'FIRST'\n" - "NullsLast <- 'NULLS' 'LAST'\n" - "OrderByClause <- 'ORDER' 'BY' OrderByExpressions\n" - "OrderByExpressions <- OrderByAll / OrderByExpressionList\n" - "OrderByExpressionList <- List(OrderByExpression)\n" - "OrderByAll <- 'ALL' DescOrAsc? NullsFirstOrLast?\n" - "LimitClause <- 'LIMIT' LimitValue\n" - "OffsetClause <- 'OFFSET' OffsetValue\n" - "OffsetValue <- Expression RowOrRows?\n" - "RowOrRows <- 'ROW' / 'ROWS'\n" - "LimitValue <- LimitAll / LimitLiteralPercent / LimitExpression\n" - "LimitAll <- 'ALL'\n" - "LimitLiteralPercent <- NumberLiteral 'PERCENT'\n" - "LimitExpression <- Expression '%'?\n" - "AliasedExpression <- ColIdExpression / ExpressionAsCollabel / ExpressionOptIdentifier\n" - "ColIdExpression <- ColId ':' Expression\n" - "ExpressionAsCollabel <- Expression 'AS' ColLabelOrString\n" - "ExpressionOptIdentifier <- Expression Identifier?\n" - "ValuesClause <- 'VALUES' List(ValuesExpressions)\n" - "ValuesExpressions <- Parens(List(Expression))\n" - "TransactionStatement <- BeginTransaction / RollbackTransaction / CommitTransaction\n" - "BeginTransaction <- StartOrBegin Transaction? ReadOrWrite?\n" - "RollbackTransaction <- AbortOrRollback Transaction?\n" - "CommitTransaction <- CommitOrEnd Transaction?\n" - "StartOrBegin <- 'START' / 'BEGIN'\n" - "Transaction <- 'WORK' / 'TRANSACTION'\n" - "ReadOrWrite <- 'READ' ReadOnlyOrReadWrite\n" - "ReadOnlyOrReadWrite <- ReadOnly / ReadWrite\n" - "ReadOnly <- 'ONLY'\n" - "ReadWrite <- 'WRITE'\n" - "AbortOrRollback <- 'ABORT' / 'ROLLBACK'\n" - "CommitOrEnd <- 'COMMIT' / 'END'\n" - "DeleteStatement <- WithClause? 'DELETE' 'FROM' TargetOptAlias DeleteUsingClause? WhereClause? ReturningClause?\n" - "TruncateStatement <- 'TRUNCATE' 'TABLE'? BaseTableName\n" - "TargetOptAlias <- BaseTableName 'AS'? ColId?\n" - "DeleteUsingClause <- 'USING' List(TableRef)\n" - "ConnectStatement <- 'CONNECT' SessionTarget?\n" - "DisconnectStatement <- 'DISCONNECT'\n" - "SessionTarget <- 'LOCAL' / StringLiteral / CatalogName\n" - "CreateTypeStmt <- 'TYPE' IfNotExists? QualifiedName 'AS' CreateType\n" - "CreateType <- EnumSelectType / EnumStringLiteralList / CreateTypeFromType\n" - "CreateTypeFromType <- Type\n" - "EnumSelectType <- 'ENUM' Parens(SelectStatementInternal)\n" - "EnumStringLiteralList <- 'ENUM' Parens(List(StringLiteral)?)\n" - "SetStatement <- 'SET' SetAssignmentOrTimeZone\n" - "SetAssignmentOrTimeZone <- StandardAssignment / SetTimeZone\n" - "ResetStatement <- 'RESET' SetVariableOrSetting\n" - "StandardAssignment <- SetVariableOrSetting SetAssignment\n" - "SetVariableOrSetting <- SetVariable / SetSetting\n" - "SetTimeZone <- 'TIME' 'ZONE' ZoneValue\n" - "ZoneValue <- ZoneIntervalWithPrecision / ZoneIntervalWithInterval / ZoneLocal / ZoneDefault / ZoneStringLiteral / " - "ZoneIdentifier / NumberLiteral\n" - "ZoneLocal <- 'LOCAL'\n" - "ZoneDefault <- 'DEFAULT'\n" - "ZoneStringLiteral <- StringLiteral\n" - "ZoneIdentifier <- Identifier\n" - "ZoneIntervalWithInterval <- 'INTERVAL' StringLiteral Interval?\n" - "ZoneIntervalWithPrecision <- 'INTERVAL' Parens(NumberLiteral) StringLiteral\n" - "SetSetting <- SettingScope? SettingName\n" - "SetVariable <- VariableScope Identifier\n" - "VariableScope <- 'VARIABLE'\n" - "SettingScope <- LocalScope / SessionScope / GlobalScope\n" - "LocalScope <- 'LOCAL'\n" - "SessionScope <- 'SESSION'\n" - "GlobalScope <- 'GLOBAL'\n" - "SetAssignment <- VariableAssign VariableList\n" - "VariableAssign <- '=' / 'TO'\n" - "VariableList <- List(Expression)\n" - "ExportStatement <- 'EXPORT' 'DATABASE' ExportSource? StringLiteral GenericCopyOptionList?\n" - "ExportSource <- CatalogName 'TO'\n" - "ImportStatement <- 'IMPORT' 'DATABASE' StringLiteral\n" - "CheckpointStatement <- CheckpointForce? 'CHECKPOINT' CatalogName?\n" - "CheckpointForce <- 'FORCE'\n" - "CopyStatement <- 'COPY' CopyVariations\n" - "CopyVariations <- CopyTable / CopySelect / CopyFromDatabase\n" - "CopyTable <- BaseTableName InsertColumnList? FromOrTo CopyFileName CopyOptions?\n" - "FromOrTo <- CopyFrom / CopyTo\n" - "CopyFrom <- 'FROM'\n" - "CopyTo <- 'TO'\n" - "CopySelect <- Parens(SelectStatementInternal) 'TO' CopyFileName CopyOptions?\n" - "CopyFileName <- CopyFileNameExpression / CopyFileNameStringLiteral / CopyFileNameIdentifier / " - "CopyFileNameIdentifierColId\n" - "CopyFileNameExpression <- Parameter / ParensExpression\n" - "CopyFileNameStringLiteral <- StringLiteral\n" - "CopyFileNameIdentifier <- Identifier\n" - "CopyFileNameIdentifierColId <- IdentifierColId\n" - "IdentifierColId <- Identifier '.' ColId\n" - "CopyOptions <- 'WITH'? CopyOptionList\n" - "CopyOptionList <- GenericCopyOptionList / SpecializedOptionList\n" - "SpecializedOptionList <- SpecializedOption*\n" - "SpecializedOption <- SingleOption / NullAsOption / DelimiterAsOption / EscapeAsOption /\n" - " EncodingOption / QuoteAsOption / ForceQuoteOption / PartitionByOption / ForceNullOption\n" - "SingleOption <- BinaryOption / FreezeOption / OidsOption / CsvOption / HeaderOption\n" - "BinaryOption <- 'BINARY'\n" - "FreezeOption <- 'FREEZE'\n" - "OidsOption <- 'OIDS'\n" - "CsvOption <- 'CSV'\n" - "HeaderOption <- 'HEADER'\n" - "NullAsOption <- 'NULL' 'AS'? StringLiteral\n" - "DelimiterAsOption <- 'DELIMITER' 'AS'? StringLiteral\n" - "QuoteAsOption <- 'QUOTE' 'AS'? StringLiteral\n" - "EscapeAsOption <- 'ESCAPE' 'AS'? StringLiteral\n" - "EncodingOption <- 'ENCODING' StringLiteral\n" - "ForceQuoteOption <- ForceQuote? 'QUOTE' StarSymbolColumnList\n" - "StarSymbolColumnList <- StarSymbol / ColumnList\n" - "ForceQuote <- 'FORCE'\n" - "PartitionByOption <- 'PARTITION' 'BY' StarSymbolColumnList\n" - "ForceNullOption <- 'FORCE' ForceNotNull? 'NULL' ColumnList\n" - "ForceNotNull <- 'NOT'\n" - "StarSymbol <- '*'\n" - "GenericCopyOptionList <- Parens(List(GenericCopyOption))\n" - "GenericCopyOption <- CopyOptionName GenericCopyOptionValue?\n" - "GenericCopyOptionValue <- GenericCopyOptionOrderList / GenericCopyOptionExpression\n" - "GenericCopyOptionOrderList <- GenericCopyOptionParenthesizedExpressionList\n" - "GenericCopyOptionExpression <- Expression\n" - "GenericCopyOptionParenthesizedExpressionList <- Parens(OrderByExpressionList)\n" - "CopyFromDatabase <- CopyFromDatabaseWithFlag / CopyFromDatabaseWithoutFlag\n" - "CopyFromDatabaseWithFlag <- 'FROM' 'DATABASE' ColId 'TO' ColId CopyDatabaseFlag\n" - "CopyFromDatabaseWithoutFlag <- 'FROM' 'DATABASE' ColId 'TO' ColId\n" - "CopyDatabaseFlag <- Parens(SchemaOrData)\n" - "SchemaOrData <- CopySchema / CopyData\n" - "CopySchema <- 'SCHEMA'\n" - "CopyData <- 'DATA'\n" - "AlterStatement <- 'ALTER' AlterOptions\n" - "AlterOptions <- AlterTableStmt / AlterViewStmt / AlterSequenceStmt / AlterDatabaseStmt / AlterSchemaStmt\n" - "AlterTableStmt <- 'TABLE' IfExists? BaseTableName List(AlterTableOptions)\n" - "AlterSchemaStmt <- 'SCHEMA' IfExists? QualifiedName RenameAlter\n" - "AlterTableOptions <- AddColumn / DropColumn / AlterColumn / AddConstraint / ChangeNullability /\n" - " RenameColumn / RenameAlter / SetPartitionedBy / ResetPartitionedBy / SetSortedBy / ResetSortedBy / " - "SetOptions / ResetOptions\n" - "AddConstraint <- 'ADD' TopLevelConstraint\n" - "AddColumn <- 'ADD' 'COLUMN'? IfNotExists? AddColumnEntry\n" - "AddColumnEntry <- DottedIdentifier Type? GeneratedColumn? ColumnConstraint*\n" - "DropColumn <- 'DROP' 'COLUMN'? IfExists? NestedColumnName DropBehavior?\n" - "AlterColumn <- 'ALTER' 'COLUMN'? NestedColumnName AlterColumnEntry\n" - "RenameColumn <- 'RENAME' 'COLUMN'? NestedColumnName 'TO' Identifier\n" - "NestedColumnName <- IdentifierDot* ColumnName\n" - "IdentifierDot <- Identifier '.'\n" - "RenameAlter <- 'RENAME' 'TO' Identifier\n" - "SetPartitionedBy <- 'SET' 'PARTITIONED' 'BY' Parens(List(Expression))\n" - "ResetPartitionedBy <- 'RESET' 'PARTITIONED' 'BY'\n" - "SetSortedBy <- 'SET' 'SORTED' 'BY' Parens(OrderByExpressions)\n" - "ResetSortedBy <- 'RESET' 'SORTED' 'BY'\n" - "SetOptions <- 'SET' RelOptionList\n" - "ResetOptions <- 'RESET' RelOptionList\n" - "AlterColumnEntry <- AddOrDropDefault / ChangeNullability / AlterType\n" - "AddOrDropDefault <- AddDefault / DropDefault\n" - "AddDefault <- 'SET' 'DEFAULT' Expression\n" - "DropDefault <- 'DROP' 'DEFAULT'\n" - "ChangeNullability <- DropOrSet 'NOT' 'NULL'\n" - "DropOrSet <- DropNullability / SetNullability\n" - "DropNullability <- 'DROP'\n" - "SetNullability <- 'SET'\n" - "AlterType <- SetData? 'TYPE' Type? UsingExpression?\n" - "SetData <- 'SET' 'DATA'?\n" - "UsingExpression <- 'USING' Expression\n" - "AlterViewStmt <- 'VIEW' IfExists? BaseTableName RenameAlter\n" - "AlterSequenceStmt <- 'SEQUENCE' IfExists? QualifiedSequenceName AlterSequenceOptions\n" - "QualifiedSequenceName <- CatalogQualification? SchemaQualification? SequenceName\n" - "AlterSequenceOptions <- RenameAlter / SetSequenceOption\n" - "SetSequenceOption <- SequenceOption+\n" - "AlterDatabaseStmt <- 'DATABASE' IfExists? Identifier 'SET' 'ALIAS' 'TO' Identifier\n" - "CreateSequenceStmt <- 'SEQUENCE' IfNotExists? QualifiedName SequenceOption*\n" - "SequenceOption <-\n" - " SeqSetCycle /\n" - " SeqSetIncrement /\n" - " SeqSetMinMax /\n" - " SeqNoMinMax /\n" - " SeqStartWith /\n" - " SeqOwnedBy\n" - "SeqSetCycle <- SeqCycle / SeqNoCycle\n" - "SeqCycle <- 'CYCLE'\n" - "SeqNoCycle <- 'NO' 'CYCLE'\n" - "SeqSetIncrement <- 'INCREMENT' 'BY'? Expression\n" - "SeqSetMinMax <- SeqMinOrMax Expression\n" - "SeqNoMinMax <- 'NO' SeqMinOrMax\n" - "SeqStartWith <- 'START' 'WITH'? Expression\n" - "SeqOwnedBy <- 'OWNED' 'BY' QualifiedName\n" - "SeqMinOrMax <- MinValue / MaxValue\n" - "MinValue <- 'MINVALUE'\n" - "MaxValue <- 'MAXVALUE'\n" - "ExplainStatement <- 'EXPLAIN' ExplainAnalyze? ExplainOptionList? ExplainableStatements\n" - "ExplainAnalyze <- 'ANALYZE'\n" - "ExplainOptionList <- Parens(List(ExplainOption))\n" - "ExplainOption <- ExplainOptionName Expression?\n" - "ExplainOptionName <- 'ANALYZE' / 'ANALYSE' / ColId / FuncNameKeyword / TypeNameKeyword\n" - "ExplainSelectStatement <- SelectStatementInternal\n" - "ExplainableStatements <-\n" - " AlterStatement /\n" - " AnalyzeStatement /\n" - " CallStatement /\n" - " CheckpointStatement /\n" - " CopyStatement /\n" - " CreateStatement /\n" - " DeallocateStatement /\n" - " DeleteStatement /\n" - " DropStatement /\n" - " ExecuteStatement /\n" - " InsertStatement /\n" - " LoadStatement /\n" - " MergeIntoStatement /\n" - " PragmaStatement /\n" - " PrepareStatement /\n" - " ExplainSelectStatement /\n" - " TransactionStatement /\n" - " UpdateStatement /\n" - " VacuumStatement /\n" - " SetStatement /\n" - " ResetStatement\n" - "AnalyzeStatement <- 'ANALYZE' AnalyzeVerbose? AnalyzeTarget?\n" - "AnalyzeTarget <- BaseTableName NameList?\n" - "AnalyzeVerbose <- 'VERBOSE'\n" - "CreateMacroStmt <- MacroOrFunction IfNotExists? QualifiedName List(MacroDefinition)\n" - "MacroOrFunction <- MacroKeyword / FunctionKeyword\n" - "MacroKeyword <- 'MACRO'\n" - "FunctionKeyword <- 'FUNCTION'\n" - "MacroDefinition <- Parens(MacroParameters?) 'AS' MacroDefinitionBody\n" - "MacroDefinitionBody <- TableMacroDefinition / ScalarMacroDefinition\n" - "MacroParameters <- List(MacroParameter)\n" - "MacroParameter <- NamedParameter / SimpleParameter\n" - "SimpleParameter <- TypeFuncName Type?\n" - "ScalarMacroDefinition <- Expression\n" - "TableMacroDefinition <- 'TABLE' SelectStatementInternal\n" - "CommentStatement <- 'COMMENT' 'ON' CommentOnType DottedIdentifier 'IS' CommentValue\n" - "CommentOnType <- CommentTable / CommentSequence / CommentFunction / CommentMacroTable / CommentMacro /\n" - " CommentView / CommentDatabase / CommentIndex / CommentSchema / CommentType / CommentColumn\n" - "CommentTable <- 'TABLE'\n" - "CommentSequence <- 'SEQUENCE'\n" - "CommentFunction <- 'FUNCTION'\n" - "CommentMacroTable <- 'MACRO' 'TABLE'\n" - "CommentMacro <- 'MACRO'\n" - "CommentView <- 'VIEW'\n" - "CommentDatabase <- 'DATABASE'\n" - "CommentIndex <- 'INDEX'\n" - "CommentSchema <- 'SCHEMA'\n" - "CommentType <- 'TYPE'\n" - "CommentColumn <- 'COLUMN'\n" - "CommentValue <- NullLiteral / StringLiteral\n" - "CreateTriggerStmt <- 'TRIGGER' IfNotExists? TriggerName TriggerTiming TriggerEvent 'ON' BaseTableName " - "ReferencingClause? ForEachClause? TriggerBody\n" - "TriggerBody <- InsertStatement / UpdateStatement / DeleteStatement\n" - "TriggerName <- Identifier\n" - "ReferencingClause <- 'REFERENCING' ReferencingItem ReferencingItem?\n" - "ReferencingItem <- ReferencingNewTableAs / ReferencingOldTableAs\n" - "ReferencingNewTableAs <- 'NEW' 'TABLE' 'AS' ColId\n" - "ReferencingOldTableAs <- 'OLD' 'TABLE' 'AS' ColId\n" - "TriggerTiming <- TriggerBefore / TriggerAfter / TriggerInsteadOf\n" - "TriggerBefore <- 'BEFORE'\n" - "TriggerAfter <- 'AFTER'\n" - "TriggerInsteadOf <- 'INSTEAD' 'OF'\n" - "TriggerEvent <- TriggerEventUpdateOf / TriggerEventInsert / TriggerEventDelete / TriggerEventUpdate\n" - "TriggerEventInsert <- 'INSERT'\n" - "TriggerEventDelete <- 'DELETE'\n" - "TriggerEventUpdate <- 'UPDATE'\n" - "TriggerEventUpdateOf <- 'UPDATE' 'OF' TriggerColumnList\n" - "TriggerColumnList <- List(ColId)\n" - "ForEachClause <- ForEachRow / ForEachStatement\n" - "ForEachRow <- 'FOR' 'EACH' 'ROW'\n" - "ForEachStatement <- 'FOR' 'EACH' 'STATEMENT'\n" - "AttachStatement <- 'ATTACH' OrReplace? IfNotExists? Database? DatabasePath AttachAlias? AttachOptions?\n" - "Database <- 'DATABASE'\n" - "DatabasePath <- Expression\n" - "AttachAlias <- 'AS' ColId\n" - "AttachOptions <- GenericCopyOptionList\n" - "DetachStatement <- 'DETACH' Database? IfExists? CatalogName\n" - "UseStatement <- 'USE' UseTarget\n" - "UseTarget <- UseTargetCatalogSchema / SchemaNameAsUseTarget / CatalogNameAsUseTarget\n" - "SchemaNameAsUseTarget <- SchemaName\n" - "CatalogNameAsUseTarget <- CatalogName\n" - "UseTargetCatalogSchema <- CatalogName '.' ReservedSchemaName DotIdentifier*\n" - "DotIdentifier <- '.' Identifier\n" - "CallStatement <- 'CALL' QualifiedTableFunction TableFunctionArguments\n" + "Program <- TopLevelStatement*\n" + "TopLevelStatement <- Statement? (';'+ / EndOfInput)\n" + "Statement <-\n" + " CreateStatement /\n" + " SelectStatement /\n" + " SetStatement /\n" + " PragmaStatement /\n" + " CallStatement /\n" + " InsertStatement /\n" + " DropStatement /\n" + " CopyStatement /\n" + " ExplainStatement /\n" + " UpdateStatement /\n" + " PrepareStatement /\n" + " ExecuteStatement /\n" + " AlterStatement /\n" + " TransactionStatement /\n" + " DeleteStatement /\n" + " AttachStatement /\n" + " UseStatement /\n" + " DetachStatement /\n" + " CheckpointStatement /\n" + " VacuumStatement /\n" + " ResetStatement /\n" + " ExportStatement /\n" + " ImportStatement /\n" + " CommentStatement /\n" + " DeallocateStatement /\n" + " TruncateStatement /\n" + " LoadStatement /\n" + " InstallStatement /\n" + " UpdateExtensionsStatement /\n" + " AnalyzeStatement /\n" + " MergeIntoStatement /\n" + " ConnectStatement /\n" + " DisconnectStatement /\n" + " ExpressionStatement\n" + "ExpressionStatement <- List(ExpressionAlias)\n" + "ExpressionAlias <- ColIdExpression / ExpressionAsCollabel / Expression\n" + "CatalogName <- Identifier\n" + "SchemaName <- Identifier\n" + "ReservedSchemaName <- Identifier\n" + "TableName <- Identifier\n" + "ReservedTableName <- Identifier\n" + "ReservedIdentifier <- Identifier\n" + "ColumnName <- Identifier\n" + "ReservedColumnName <- Identifier\n" + "IndexName <- Identifier\n" + "ReservedIndexName <- Identifier\n" + "SettingName <- Identifier\n" + "PragmaName <- Identifier\n" + "FunctionName <- Identifier\n" + "ReservedFunctionName <- Identifier\n" + "ReservedTypeName <- Identifier\n" + "TableFunctionName <- Identifier\n" + "ConstraintName <- ColIdOrString\n" + "SequenceName <- Identifier\n" + "CollationName <- Identifier\n" + "CopyOptionName <- ColLabel\n" + "NumberLiteral <- < [+-]?[0-9]*([.][0-9]*)? >\n" + "StringLiteral <- '\\'' [^\\']* '\\''\n" + "Type <- TypeVariations ArrayBounds*\n" + "TypeVariations <- TimeType / IntervalType / BitType / RowType / VariantType / MapType / GeometryType / UnionType / NumericType / SetofType / SimpleType\n" + "SimpleType <- CharacterSimpleType / QualifiedSimpleType\n" + "CharacterSimpleType <- CharacterType TypeModifiers?\n" + "QualifiedSimpleType <- QualifiedTypeName TypeModifiers?\n" + "CharacterType <- ('CHARACTER' 'VARYING'?) /\n" + " ('CHAR' 'VARYING'?) /\n" + " ('NATIONAL' 'CHARACTER' 'VARYING'?) /\n" + " ('NATIONAL' 'CHAR' 'VARYING'?) /\n" + " ('NCHAR' 'VARYING'?) /\n" + " 'VARCHAR'\n" + "IntervalType <- IntervalInterval / IntervalNumber\n" + "IntervalInterval <- IntervalWithSpecifier / IntervalWithoutSpecifier\n" + "IntervalWithSpecifier <- IntervalWithRangeSpecifier / IntervalWithSimpleSpecifier\n" + "IntervalWithRangeSpecifier <- 'INTERVAL' IntervalToIntervalAsType\n" + "IntervalWithSimpleSpecifier <- 'INTERVAL' Interval\n" + "IntervalWithoutSpecifier <- 'INTERVAL'\n" + "IntervalToIntervalAsType <- (YearKeyword 'TO' MonthKeyword) /\n" + " (DayKeyword 'TO' HourKeyword) /\n" + " (DayKeyword 'TO' MinuteKeyword) /\n" + " (DayKeyword 'TO' SecondKeyword) /\n" + " (HourKeyword 'TO' MinuteKeyword) /\n" + " (HourKeyword 'TO' SecondKeyword) /\n" + " (MinuteKeyword 'TO' SecondKeyword)\n" + "IntervalNumber <- 'INTERVAL' Parens(NumberLiteral)\n" + "YearKeyword <- 'YEAR' / 'YEARS'\n" + "MonthKeyword <- 'MONTH' / 'MONTHS'\n" + "DayKeyword <- 'DAY' / 'DAYS'\n" + "HourKeyword <- 'HOUR' / 'HOURS'\n" + "MinuteKeyword <- 'MINUTE' / 'MINUTES'\n" + "SecondKeyword <- 'SECOND' / 'SECONDS'\n" + "MillisecondKeyword <- 'MILLISECOND' / 'MILLISECONDS'\n" + "MicrosecondKeyword <- 'MICROSECOND' / 'MICROSECONDS'\n" + "WeekKeyword <- 'WEEK' / 'WEEKS'\n" + "QuarterKeyword <- 'QUARTER' / 'QUARTERS'\n" + "DecadeKeyword <- 'DECADE' / 'DECADES'\n" + "CenturyKeyword <- 'CENTURY' / 'CENTURIES'\n" + "MillenniumKeyword <- 'MILLENNIUM' / 'MILLENNIA'\n" + "Interval <- IntervalToInterval /\n" + " YearKeyword /\n" + " MonthKeyword /\n" + " DayKeyword /\n" + " HourKeyword /\n" + " MinuteKeyword /\n" + " SecondKeyword /\n" + " MillisecondKeyword /\n" + " MicrosecondKeyword /\n" + " WeekKeyword /\n" + " QuarterKeyword /\n" + " DecadeKeyword /\n" + " CenturyKeyword /\n" + " MillenniumKeyword\n" + "IntervalToInterval <- YearToMonth /\n" + " DayToHour /\n" + " DayToMinute /\n" + " DayToSecond /\n" + " HourToMinute /\n" + " HourToSecond /\n" + " MinuteToSecond\n" + "YearToMonth <- YearKeyword 'TO' MonthKeyword\n" + "DayToHour <- DayKeyword 'TO' HourKeyword\n" + "DayToMinute <- DayKeyword 'TO' MinuteKeyword\n" + "DayToSecond <- DayKeyword 'TO' SecondKeyword\n" + "HourToMinute <- HourKeyword 'TO' MinuteKeyword\n" + "HourToSecond <- HourKeyword 'TO' SecondKeyword\n" + "MinuteToSecond <- MinuteKeyword 'TO' SecondKeyword\n" + "BitType <- 'BIT' 'VARYING'? Parens(List(Expression))?\n" + "GeometryType <- 'GEOMETRY' Parens(Expression)?\n" + "VariantType <- 'VARIANT'\n" + "NumericType <- SimpleNumericType / DecimalNumericType\n" + "SimpleNumericType <- IntType / IntegerType / SmallintType /\n" + " BigintType / RealType / BooleanType / DoubleType\n" + "DecimalNumericType <- FloatType / DecimalType / DecType / NumericModType\n" + "IntType <- 'INT'\n" + "IntegerType <- 'INTEGER'\n" + "SmallintType <- 'SMALLINT'\n" + "BigintType <- 'BIGINT'\n" + "RealType <- 'REAL'\n" + "BooleanType <- 'BOOLEAN'\n" + "DoubleType <- ('DOUBLE' 'PRECISION')\n" + "FloatType <- 'FLOAT' Parens(NumberLiteral)?\n" + "DecimalType <- 'DECIMAL' TypeModifiers?\n" + "DecType <- 'DEC' TypeModifiers?\n" + "NumericModType <- 'NUMERIC' TypeModifiers?\n" + "QualifiedTypeName <- CatalogReservedSchemaTypeName / SchemaReservedTypeName / TypeNameAsQualifiedName\n" + "TypeNameAsQualifiedName <- TypeName\n" + "CatalogReservedSchemaTypeName <- CatalogQualification ReservedSchemaQualification ReservedTypeName\n" + "SchemaReservedTypeName <- SchemaQualification ReservedTypeName\n" + "TypeModifiers <- Parens(List(Expression)?)\n" + "RowType <- RowOrStruct ColIdTypeList\n" + "SetofType <- 'SETOF' Type\n" + "UnionType <- 'UNION' ColIdTypeList\n" + "ColIdTypeList <- Parens(List(ColIdType))\n" + "MapType <- 'MAP' Parens(List(Type))\n" + "ColIdType <- ColId Type\n" + "ArrayBounds <- SquareBracketsArray / ArrayKeyword\n" + "ArrayKeyword <- 'ARRAY'\n" + "SquareBracketsArray <- '[' Expression? ']'\n" + "TimeType <- TimeOrTimestamp TypeModifiers? TimeZone?\n" + "TimeOrTimestamp <- TimeTypeId / TimestampTypeId\n" + "TimeTypeId <- 'TIME'\n" + "TimestampTypeId <- 'TIMESTAMP'\n" + "TimeZone <- WithOrWithout 'TIME' 'ZONE'\n" + "WithOrWithout <- WithRule / WithoutRule\n" + "WithRule <- 'WITH'\n" + "WithoutRule <- 'WITHOUT'\n" + "RowOrStruct <- 'ROW' / 'STRUCT'\n" + "# internal definitions\n" + "%whitespace <- [ \\t\\n\\r]*\n" + "List(D) <- D (',' D)* ','?\n" + "Parens(D) <- '(' D ')'\n" + "UnreservedKeyword <- 'ABORT' /\n" + "'ABSOLUTE' /\n" + "'ACCESS' /\n" + "'ACTION' /\n" + "'ADD' /\n" + "'ADMIN' /\n" + "'AFTER' /\n" + "'AGGREGATE' /\n" + "'ALSO' /\n" + "'ALTER' /\n" + "'ALWAYS' /\n" + "'ASSERTION' /\n" + "'ASSIGNMENT' /\n" + "'ATTACH' /\n" + "'ATTRIBUTE' /\n" + "'BACKWARD' /\n" + "'BEFORE' /\n" + "'BEGIN' /\n" + "'CACHE' /\n" + "'CALL' /\n" + "'CALLED' /\n" + "'CASCADE' /\n" + "'CASCADED' /\n" + "'CATALOG' /\n" + "'CENTURY' /\n" + "'CENTURIES' /\n" + "'CHAIN' /\n" + "'CHARACTERISTICS' /\n" + "'CHECKPOINT' /\n" + "'CLASS' /\n" + "'CLOSE' /\n" + "'CLUSTER' /\n" + "'COMMENT' /\n" + "'COMMENTS' /\n" + "'COMMIT' /\n" + "'COMMITTED' /\n" + "'COMPRESSION' /\n" + "'CONFIGURATION' /\n" + "'CONFLICT' /\n" + "'CONNECT' /\n" + "'CONNECTION' /\n" + "'CONSTRAINTS' /\n" + "'CONTENT' /\n" + "'CONTINUE' /\n" + "'CONVERSION' /\n" + "'COPY' /\n" + "'COST' /\n" + "'CSV' /\n" + "'CUBE' /\n" + "'CURRENT' /\n" + "'CURSOR' /\n" + "'CYCLE' /\n" + "'DATA' /\n" + "'DATABASE' /\n" + "'DAY' /\n" + "'DAYS' /\n" + "'DEALLOCATE' /\n" + "'DECADE' /\n" + "'DECADES' /\n" + "'DECLARE' /\n" + "'DEFAULTS' /\n" + "'DEFERRED' /\n" + "'DEFINER' /\n" + "'DELETE' /\n" + "'DELIMITER' /\n" + "'DELIMITERS' /\n" + "'DEPENDS' /\n" + "'DETACH' /\n" + "'DICTIONARY' /\n" + "'DISABLE' /\n" + "'DISCARD' /\n" + "'DISCONNECT' /\n" + "'DOCUMENT' /\n" + "'DOMAIN' /\n" + "'DOUBLE' /\n" + "'DROP' /\n" + "'EACH' /\n" + "'ENABLE' /\n" + "'ENCODING' /\n" + "'ENCRYPTED' /\n" + "'ENUM' /\n" + "'ERROR' /\n" + "'ESCAPE' /\n" + "'EVENT' /\n" + "'EXCLUDE' /\n" + "'EXCLUDING' /\n" + "'EXCLUSIVE' /\n" + "'EXECUTE' /\n" + "'EXPLAIN' /\n" + "'EXPORT' /\n" + "'EXPORT_STATE' /\n" + "'EXTENSION' /\n" + "'EXTENSIONS' /\n" + "'EXTERNAL' /\n" + "'FAMILY' /\n" + "'FILTER' /\n" + "'FIRST' /\n" + "'FOLLOWING' /\n" + "'FORCE' /\n" + "'FORWARD' /\n" + "'FUNCTION' /\n" + "'FUNCTIONS' /\n" + "'GLOBAL' /\n" + "'GRANT' /\n" + "'GRANTED' /\n" + "'GROUPS' /\n" + "'HANDLER' /\n" + "'HEADER' /\n" + "'HOLD' /\n" + "'HOUR' /\n" + "'HOURS' /\n" + "'IDENTITY' /\n" + "'IF' /\n" + "'IGNORE' /\n" + "'IMMEDIATE' /\n" + "'IMMUTABLE' /\n" + "'IMPLICIT' /\n" + "'IMPORT' /\n" + "'INCLUDE' /\n" + "'INCLUDING' /\n" + "'INCREMENT' /\n" + "'INDEX' /\n" + "'INDEXES' /\n" + "'INHERIT' /\n" + "'INHERITS' /\n" + "'INLINE' /\n" + "'INPUT' /\n" + "'INSENSITIVE' /\n" + "'INSERT' /\n" + "'INSTALL' /\n" + "'INSTEAD' /\n" + "'INVOKER' /\n" + "'JSON' /\n" + "'ISOLATION' /\n" + "'KEY' /\n" + "'LABEL' /\n" + "'LANGUAGE' /\n" + "'LARGE' /\n" + "'LAST' /\n" + "'LEAKPROOF' /\n" + "'LEVEL' /\n" + "'LISTEN' /\n" + "'LOAD' /\n" + "'LOCAL' /\n" + "'LOCATION' /\n" + "'LOCK' /\n" + "'LOCKED' /\n" + "'LOGGED' /\n" + "'MACRO' /\n" + "'MAPPING' /\n" + "'MATCH' /\n" + "'MATCHED' /\n" + "'MATERIALIZED' /\n" + "'MAXVALUE' /\n" + "'MERGE' /\n" + "'METHOD' /\n" + "'MICROSECOND' /\n" + "'MICROSECONDS' /\n" + "'MILLENNIUM' /\n" + "'MILLENNIA' /\n" + "'MILLISECOND' /\n" + "'MILLISECONDS' /\n" + "'MINUTE' /\n" + "'MINUTES' /\n" + "'MINVALUE' /\n" + "'MODE' /\n" + "'MONTH' /\n" + "'MONTHS' /\n" + "'MOVE' /\n" + "'NAME' /\n" + "'NAMES' /\n" + "'NEW' /\n" + "'NEXT' /\n" + "'NO' /\n" + "'NOTHING' /\n" + "'NOTIFY' /\n" + "'NOWAIT' /\n" + "'NULLS' /\n" + "'OBJECT' /\n" + "'OF' /\n" + "'OFF' /\n" + "'OIDS' /\n" + "'OLD' /\n" + "'OPERATOR' /\n" + "'OPTION' /\n" + "'OPTIONS' /\n" + "'ORDINALITY' /\n" + "'OTHERS' /\n" + "'OVER' /\n" + "'OVERRIDING' /\n" + "'OWNED' /\n" + "'OWNER' /\n" + "'PARALLEL' /\n" + "'PARSER' /\n" + "'PARTIAL' /\n" + "'PARTITION' /\n" + "'PARTITIONED' /\n" + "'PASSING' /\n" + "'PASSWORD' /\n" + "'PERCENT' /\n" + "'PERSISTENT' /\n" + "'PLANS' /\n" + "'POLICY' /\n" + "'PRAGMA' /\n" + "'PRECEDING' /\n" + "'PREPARE' /\n" + "'PREPARED' /\n" + "'PRESERVE' /\n" + "'PRIOR' /\n" + "'PRIVILEGES' /\n" + "'PROCEDURAL' /\n" + "'PROCEDURE' /\n" + "'PROGRAM' /\n" + "'PUBLICATION' /\n" + "'QUARTER' /\n" + "'QUARTERS' /\n" + "'QUOTE' /\n" + "'RANGE' /\n" + "'READ' /\n" + "'REASSIGN' /\n" + "'RECHECK' /\n" + "'RECURSIVE' /\n" + "'REF' /\n" + "'REFERENCING' /\n" + "'REFRESH' /\n" + "'REINDEX' /\n" + "'RELATIVE' /\n" + "'RELEASE' /\n" + "'RENAME' /\n" + "'REPEATABLE' /\n" + "'REPLACE' /\n" + "'REPLICA' /\n" + "'RESET' /\n" + "'RESPECT' /\n" + "'RESTART' /\n" + "'RESTRICT' /\n" + "'RETURNS' /\n" + "'REVOKE' /\n" + "'ROLE' /\n" + "'ROLLBACK' /\n" + "'ROLLUP' /\n" + "'ROWS' /\n" + "'RULE' /\n" + "'SAMPLE' /\n" + "'SAVEPOINT' /\n" + "'SCHEMA' /\n" + "'SCHEMAS' /\n" + "'SCOPE' /\n" + "'SCROLL' /\n" + "'SEARCH' /\n" + "'SECRET' /\n" + "'SECOND' /\n" + "'SECONDS' /\n" + "'SECURITY' /\n" + "'SEQUENCE' /\n" + "'SEQUENCES' /\n" + "'SERIALIZABLE' /\n" + "'SERVER' /\n" + "'SESSION' /\n" + "'SET' /\n" + "'SETS' /\n" + "'SHARE' /\n" + "'SIMPLE' /\n" + "'SKIP' /\n" + "'SNAPSHOT' /\n" + "'SORTED' /\n" + "'SOURCE' /\n" + "'SQL' /\n" + "'STABLE' /\n" + "'STANDALONE' /\n" + "'START' /\n" + "'STATEMENT' /\n" + "'STATISTICS' /\n" + "'STDIN' /\n" + "'STDOUT' /\n" + "'STORAGE' /\n" + "'STORED' /\n" + "'STRICT' /\n" + "'STRIP' /\n" + "'SUBSCRIPTION' /\n" + "'SYSID' /\n" + "'SYSTEM' /\n" + "'TABLES' /\n" + "'TABLESPACE' /\n" + "'TARGET' /\n" + "'TEMP' /\n" + "'TEMPLATE' /\n" + "'TEMPORARY' /\n" + "'TEXT' /\n" + "'TIES' /\n" + "'TRANSACTION' /\n" + "'TRANSFORM' /\n" + "'TRIGGER' /\n" + "'TRUNCATE' /\n" + "'TRUSTED' /\n" + "'TYPE' /\n" + "'TYPES' /\n" + "'UNBOUNDED' /\n" + "'UNCOMMITTED' /\n" + "'UNENCRYPTED' /\n" + "'UNKNOWN' /\n" + "'UNLISTEN' /\n" + "'UNLOGGED' /\n" + "'UNTIL' /\n" + "'UPDATE' /\n" + "'USE' /\n" + "'USER' /\n" + "'VACUUM' /\n" + "'VALID' /\n" + "'VALIDATE' /\n" + "'VALIDATOR' /\n" + "'VALUE' /\n" + "'VARIABLE' /\n" + "'VARYING' /\n" + "'VERSION' /\n" + "'VIEW' /\n" + "'VIEWS' /\n" + "'VIRTUAL' /\n" + "'VOLATILE' /\n" + "'WEEK' /\n" + "'WEEKS' /\n" + "'WHITESPACE' /\n" + "'WITHIN' /\n" + "'WITHOUT' /\n" + "'WORK' /\n" + "'WRAPPER' /\n" + "'WRITE' /\n" + "'XML' /\n" + "'YEAR' /\n" + "'YEARS' /\n" + "'YES' /\n" + "'ZONE'\n" + "ReservedKeyword <- 'ALL' /\n" + "'ANALYSE' /\n" + "'ANALYZE' /\n" + "'AND' /\n" + "'ANY' /\n" + "'ARRAY' /\n" + "'AS' /\n" + "'ASC' /\n" + "'ASYMMETRIC' /\n" + "'BOTH' /\n" + "'CASE' /\n" + "'CAST' /\n" + "'CHECK' /\n" + "'COLLATE' /\n" + "'COLUMN' /\n" + "'CONSTRAINT' /\n" + "'CREATE' /\n" + "'DEFAULT' /\n" + "'DEFERRABLE' /\n" + "'DESC' /\n" + "'DESCRIBE' /\n" + "'DISTINCT' /\n" + "'DO' /\n" + "'ELSE' /\n" + "'END' /\n" + "'EXCEPT' /\n" + "'FALSE' /\n" + "'FETCH' /\n" + "'FOR' /\n" + "'FOREIGN' /\n" + "'FROM' /\n" + "'GROUP' /\n" + "'HAVING' /\n" + "'QUALIFY' /\n" + "'IN' /\n" + "'INITIALLY' /\n" + "'INTERSECT' /\n" + "'INTO' /\n" + "'LAMBDA' /\n" + "'LATERAL' /\n" + "'LEADING' /\n" + "'LIMIT' /\n" + "'NOT' /\n" + "'NULL' /\n" + "'OFFSET' /\n" + "'ON' /\n" + "'ONLY' /\n" + "'OR' /\n" + "'ORDER' /\n" + "'PIVOT' /\n" + "'PIVOT_WIDER' /\n" + "'PIVOT_LONGER' /\n" + "'PLACING' /\n" + "'PRIMARY' /\n" + "'REFERENCES' /\n" + "'RETURNING' /\n" + "'SELECT' /\n" + "'SHOW' /\n" + "'SOME' /\n" + "'SUMMARIZE' /\n" + "'SYMMETRIC' /\n" + "'TABLE' /\n" + "'THEN' /\n" + "'TO' /\n" + "'TRAILING' /\n" + "'TRUE' /\n" + "'UNION' /\n" + "'UNIQUE' /\n" + "'UNPIVOT' /\n" + "'USING' /\n" + "'VARIADIC' /\n" + "'WHEN' /\n" + "'WHERE' /\n" + "'WINDOW' /\n" + "'WITH'\n" + "ColumnNameKeyword <- 'BETWEEN' /\n" + "'BIGINT' /\n" + "'BIT' /\n" + "'BOOLEAN' /\n" + "'CHAR' /\n" + "'CHARACTER' /\n" + "'COALESCE' /\n" + "'COLUMNS' /\n" + "'DEC' /\n" + "'DECIMAL' /\n" + "'EXISTS' /\n" + "'EXTRACT' /\n" + "'FLOAT' /\n" + "'GENERATED' /\n" + "'GROUPING' /\n" + "'GROUPING_ID' /\n" + "'INOUT' /\n" + "'INT' /\n" + "'INTEGER' /\n" + "'INTERVAL' /\n" + "'MAP' /\n" + "'NATIONAL' /\n" + "'NCHAR' /\n" + "'NONE' /\n" + "'NULLIF' /\n" + "'NUMERIC' /\n" + "'OUT' /\n" + "'OVERLAY' /\n" + "'POSITION' /\n" + "'PRECISION' /\n" + "'REAL' /\n" + "'ROW' /\n" + "'SETOF' /\n" + "'SMALLINT' /\n" + "'SUBSTRING' /\n" + "'STRUCT' /\n" + "'TIME' /\n" + "'TIMESTAMP' /\n" + "'TREAT' /\n" + "'TRIM' /\n" + "'TRY_CAST' /\n" + "'VALUES' /\n" + "'VARCHAR' /\n" + "'XMLATTRIBUTES' /\n" + "'XMLCONCAT' /\n" + "'XMLELEMENT' /\n" + "'XMLEXISTS' /\n" + "'XMLFOREST' /\n" + "'XMLNAMESPACES' /\n" + "'XMLPARSE' /\n" + "'XMLPI' /\n" + "'XMLROOT' /\n" + "'XMLSERIALIZE' /\n" + "'XMLTABLE'\n" + "FuncNameKeyword <- 'ASOF' /\n" + "'AT' /\n" + "'AUTHORIZATION' /\n" + "'BINARY' /\n" + "'COLLATION' /\n" + "'CONCURRENTLY' /\n" + "'CROSS' /\n" + "'FREEZE' /\n" + "'FULL' /\n" + "'GENERATED' /\n" + "'GLOB' /\n" + "'ILIKE' /\n" + "'INNER' /\n" + "'IS' /\n" + "'ISNULL' /\n" + "'JOIN' /\n" + "'LEFT' /\n" + "'LIKE' /\n" + "'MAP' /\n" + "'NATURAL' /\n" + "'NOTNULL' /\n" + "'OUTER' /\n" + "'OVERLAPS' /\n" + "'POSITIONAL' /\n" + "'RIGHT' /\n" + "'SIMILAR' /\n" + "'STRUCT' /\n" + "'TABLESAMPLE' /\n" + "'VERBOSE'\n" + "TypeNameKeyword <- 'ASOF' /\n" + "'AT' /\n" + "'AUTHORIZATION' /\n" + "'BINARY' /\n" + "'BY' /\n" + "'COLLATION' /\n" + "'COLUMNS' /\n" + "'CONCURRENTLY' /\n" + "'CROSS' /\n" + "'FREEZE' /\n" + "'FULL' /\n" + "'GLOB' /\n" + "'ILIKE' /\n" + "'INNER' /\n" + "'IS' /\n" + "'ISNULL' /\n" + "'JOIN' /\n" + "'LEFT' /\n" + "'LIKE' /\n" + "'NATURAL' /\n" + "'NOTNULL' /\n" + "'OUTER' /\n" + "'OVERLAPS' /\n" + "'POSITIONAL' /\n" + "'RIGHT' /\n" + "'UNPACK' /\n" + "'SIMILAR' /\n" + "'TABLESAMPLE' /\n" + "'TRY_CAST' /\n" + "'VERBOSE' /\n" + "'SEMI' /\n" + "'ANTI'\n" + "PivotStatement <- PivotKeyword TableRef PivotOn? PivotUsing? PivotGroupByList?\n" + "PivotOn <- 'ON' PivotColumnList\n" + "PivotUsing <- 'USING' TargetList\n" + "PivotColumnList <- List(PivotColumnEntry)\n" + "PivotColumnEntry <- PivotColumnSubquery / PivotValueList / PivotColumnExpression\n" + "PivotColumnExpression <- Expression\n" + "PivotColumnSubquery <- BaseExpression 'IN' Parens(SelectStatementInternal)\n" + "PivotKeyword <- 'PIVOT' / 'PIVOT_WIDER'\n" + "UnpivotKeyword <- 'UNPIVOT' / 'PIVOT_LONGER'\n" + "UnpivotStatement <- UnpivotKeyword TableRef 'ON' TargetList IntoNameValues?\n" + "IntoNameValues <- 'INTO' 'NAME' ColIdOrString ValueOrValues List(Identifier)\n" + "ValueOrValues <- 'VALUE' / 'VALUES'\n" + "IncludeOrExcludeNulls <- IncludeNulls / ExcludeNulls\n" + "IncludeNulls <- 'INCLUDE' 'NULLS'\n" + "ExcludeNulls <- 'EXCLUDE' 'NULLS'\n" + "UnpivotHeader <- UnpivotHeaderSingle / UnpivotHeaderList\n" + "UnpivotHeaderSingle <- ColIdOrString\n" + "UnpivotHeaderList <- Parens(List(ColIdOrString))\n" + "ColumnReference <- CatalogReservedSchemaTableColumnName / SchemaReservedTableColumnName / TableReservedColumnName / NestedColumnName\n" + "CatalogReservedSchemaTableColumnName <- CatalogQualification ReservedSchemaQualification ReservedTableQualification ReservedColumnName\n" + "SchemaReservedTableColumnName <- SchemaQualification ReservedTableQualification ReservedColumnName\n" + "TableReservedColumnName <- TableQualification ReservedColumnName\n" + "FunctionExpression <- FunctionIdentifier Parens(DistinctOrAll? List(FunctionArgument)? OrderByClause? IgnoreOrRespectNulls?) WithinGroupClause? FilterClause? ExportClause? OverClause?\n" + "FunctionIdentifier <- CatalogReservedSchemaFunctionName / SchemaReservedFunctionName / FunctionName\n" + "CatalogReservedSchemaFunctionName <- CatalogQualification ReservedSchemaQualification? ReservedFunctionName\n" + "SchemaReservedFunctionName <- SchemaQualification ReservedFunctionName\n" + "DistinctOrAll <- 'DISTINCT' / 'ALL'\n" + "ExportClause <- 'EXPORT_STATE'\n" + "WithinGroupClause <- 'WITHIN' 'GROUP' Parens(OrderByClause)\n" + "FilterClause <- 'FILTER' Parens('WHERE'? Expression)\n" + "IgnoreOrRespectNulls <- IgnoreNulls / RespectNulls\n" + "IgnoreNulls <- 'IGNORE' 'NULLS'\n" + "RespectNulls <- 'RESPECT' 'NULLS'\n" + "ParenthesisExpression <- Parens(List(Expression))\n" + "LiteralExpression <- StringLiteral / NumberLiteral / ConstantLiteral\n" + "ConstantLiteral <- NullLiteral / TrueLiteral / FalseLiteral\n" + "NullLiteral <- 'NULL'\n" + "TrueLiteral <- 'TRUE'\n" + "FalseLiteral <- 'FALSE'\n" + "CastExpression <- CastOrTryCast Parens(Expression 'AS' Type)\n" + "CastOrTryCast <- 'CAST' / 'TRY_CAST'\n" + "ColIdDot <- ColId '.'\n" + "StarExpression <- ColIdDot* '*' ExcludeList? ReplaceList? RenameList?\n" + "ExcludeList <- ExcludeOrExcept ExcludeNameList / ExcludeNameSingle\n" + "ExcludeOrExcept <- 'EXCLUDE' / 'EXCEPT'\n" + "ExcludeNameList <- Parens(List(ExcludeName))\n" + "ExcludeNameSingle <- ExcludeName\n" + "ExcludeName <- DottedIdentifier / ColIdOrString\n" + "ReplaceList <- 'REPLACE' ReplaceEntries\n" + "ReplaceEntries <- ReplaceEntrySingle / ReplaceEntryList\n" + "ReplaceEntrySingle <- ReplaceEntry\n" + "ReplaceEntryList <- Parens(List(ReplaceEntry))\n" + "ReplaceEntry <- Expression 'AS' ColumnReference\n" + "RenameList <- 'RENAME' (RenameEntryList / SingleRenameEntry)\n" + "RenameEntryList <- Parens(List(RenameEntry))\n" + "SingleRenameEntry <- RenameEntry\n" + "RenameEntry <- ExcludeName 'AS' Identifier\n" + "SubqueryExpression <- 'NOT'? 'EXISTS'? SubqueryReference\n" + "CaseExpression <- 'CASE' Expression? CaseWhenThen+ CaseElse? 'END'\n" + "CaseWhenThen <- 'WHEN' Expression 'THEN' Expression\n" + "CaseElse <- 'ELSE' Expression\n" + "TypeLiteral <- ColId StringLiteral\n" + "IntervalLiteral <- 'INTERVAL' IntervalParameter Interval?\n" + "IntervalParameter <- StringLiteral / NumberLiteral / ParensExpression\n" + "FrameClause <- Framing FrameExtent WindowExcludeClause?\n" + "Framing <- 'ROWS' / 'RANGE' / 'GROUPS'\n" + "FrameExtent <- BetweenFrameExtent / SingleFrameExtent\n" + "SingleFrameExtent <- FrameBound\n" + "BetweenFrameExtent <- 'BETWEEN' FrameBound 'AND' FrameBound\n" + "FrameBound <- FrameUnbounded / FrameCurrentRow / FrameExpression\n" + "FrameUnbounded <- 'UNBOUNDED' PrecedingOrFollowing\n" + "FrameExpression <- Expression PrecedingOrFollowing\n" + "FrameCurrentRow <- 'CURRENT' 'ROW'\n" + "PrecedingOrFollowing <- 'PRECEDING' / 'FOLLOWING'\n" + "WindowExcludeClause <- 'EXCLUDE' WindowExcludeElement\n" + "WindowExcludeElement <- ExcludeCurrentRow / ExcludeGroup / ExcludeTies / ExcludeNoOthers\n" + "ExcludeCurrentRow <- 'CURRENT' 'ROW'\n" + "ExcludeGroup <- 'GROUP'\n" + "ExcludeTies <- 'TIES'\n" + "ExcludeNoOthers <- 'NO' 'OTHERS'\n" + "OverClause <- 'OVER' WindowFrame\n" + "WindowFrame <- ParensIdentifier / WindowFrameDefinition / Identifier\n" + "ParensIdentifier <- Parens(Identifier)\n" + "WindowFrameDefinition <- WindowFrameNameContentsParens / WindowFrameContentsParens\n" + "WindowFrameNameContentsParens <- Parens(BaseWindowName? WindowFrameContents)\n" + "WindowFrameContentsParens <- Parens(WindowFrameContents)\n" + "WindowFrameContents <- WindowPartition? OrderByClause? FrameClause?\n" + "BaseWindowName <- Identifier\n" + "WindowPartition <- 'PARTITION' 'BY' List(Expression)\n" + "ListExpression <- ArrayBoundedListExpression / ArrayParensSelect\n" + "ArrayBoundedListExpression <- 'ARRAY'? BoundedListExpression\n" + "ArrayParensSelect <- 'ARRAY' Parens(SelectStatementInternal)\n" + "BoundedListExpression <- '[' List(Expression)? ']'\n" + "StructExpression <- '{' List(StructField) '}'\n" + "StructField <- ColIdOrString ':' Expression\n" + "MapExpression <- 'MAP' MapStructExpression\n" + "MapStructExpression <- '{' List(MapStructField)? '}'\n" + "MapStructField <- Expression ':' Expression\n" + "GroupingExpression <- GroupingOrGroupingId Parens(List(Expression)?)\n" + "GroupingOrGroupingId <- 'GROUPING' / 'GROUPING_ID'\n" + "Parameter <- QuestionMarkNumberedParameter / AnonymousParameter / NumberedParameter / ColLabelParameter\n" + "QuestionMarkNumberedParameter <- '?' NumberLiteral\n" + "AnonymousParameter <- '?'\n" + "NumberedParameter <- '$' NumberLiteral\n" + "ColLabelParameter <- '$' ColLabel\n" + "PositionalExpression <- '#' NumberLiteral\n" + "DefaultExpression <- 'DEFAULT'\n" + "ListComprehensionExpression <- '[' Expression 'FOR' List(ColIdOrString) 'IN' Expression ListComprehensionFilter? ']'\n" + "ListComprehensionFilter <- 'IF' Expression\n" + "ParensExpression <- Parens(Expression)\n" + "SingleExpression <-\n" + " ParensExpression /\n" + " LiteralExpression /\n" + " Parameter /\n" + " SubqueryExpression /\n" + " SpecialFunctionExpression /\n" + " ParenthesisExpression /\n" + " IntervalLiteral /\n" + " TypeLiteral /\n" + " CaseExpression /\n" + " StarExpression /\n" + " CastExpression /\n" + " GroupingExpression /\n" + " MapExpression /\n" + " FunctionExpression /\n" + " ColumnReference /\n" + " ListComprehensionExpression /\n" + " ListExpression /\n" + " StructExpression /\n" + " PositionalExpression /\n" + " DefaultExpression\n" + "# LEVEL 1 (Lowest)\n" + "Expression <- LambdaArrowExpression\n" + "ColumnDefaultExpr <- ColDefOrExpr\n" + "# LEVEL 1.5\n" + "LambdaArrowExpression <- LogicalOrExpression SingleArrowPair*\n" + "SingleArrowPair <- '->' LogicalOrExpression\n" + "LogicalOrExpression <- LogicalAndExpression ('OR' LogicalAndExpression)*\n" + "ColDefOrExpr <- ColDefAndExpr ('OR' ColDefAndExpr)*\n" + "# LEVEL 2\n" + "LogicalAndExpression <- LogicalNotExpression ('AND' LogicalNotExpression)*\n" + "ColDefAndExpr <- IsDistinctFromExpression ('AND' IsDistinctFromExpression)*\n" + "# LEVEL 3\n" + "LogicalNotExpression <- 'NOT'* IsExpression\n" + "# LEVEL 4\n" + "IsExpression <- IsDistinctFromExpression IsTest*\n" + "IsTest <- IsLiteral / NotNull / IsNull\n" + "IsLiteral <- 'IS' 'NOT'? (TrueLiteral / FalseLiteral / NullLiteral / UnknownLiteral)\n" + "UnknownLiteral <- 'UNKNOWN'\n" + "NotNull <- ('NOT' 'NULL') / 'NOTNULL'\n" + "IsNull <- 'ISNULL'\n" + "# LEVEL 5 (Split because IsDistinctFromExpression allows post expression while IsOperator does not)\n" + "IsDistinctFromExpression <- ComparisonExpression (IsDistinctFromOp ComparisonExpression)*\n" + "IsDistinctFromOp <- 'IS' 'NOT'? 'DISTINCT' 'FROM'\n" + "# LEVEL 6\n" + "ComparisonExpression <- BetweenInLikeExpression (ComparisonOperator 'NOT'* BetweenInLikeExpression)*\n" + "ComparisonOperator <-\n" + " OperatorEqual /\n" + " OperatorNotEqual /\n" + " OperatorLessThan /\n" + " OperatorGreaterThan /\n" + " OperatorLessThanEquals /\n" + " OperatorGreaterThanEquals\n" + "OperatorEqual <- '=' / '=='\n" + "OperatorNotEqual <- '!=' / '<>'\n" + "OperatorLessThan <- '<'\n" + "OperatorGreaterThan <- '>'\n" + "OperatorLessThanEquals <- '<='\n" + "OperatorGreaterThanEquals <- '>='\n" + "# LEVEL 7\n" + "BetweenInLikeExpression <- OtherOperatorExpression BetweenInLikeOp?\n" + "BetweenInLikeOp <- 'NOT'? (BetweenClause / InClause / LikeClause)\n" + "LikeClause <- LikeVariations OtherOperatorExpression EscapeClause?\n" + "EscapeClause <- 'ESCAPE' ComparisonExpression\n" + "LikeVariations <- SimilarToToken / ILikeToken / LikeToken / GlobToken / NotILikeOp / NotLikeOp / NotSimilarToOp\n" + "LikeToken <- 'LIKE' / '~~'\n" + "ILikeToken <- 'ILIKE' / '~~*'\n" + "GlobToken <- 'GLOB' / '~~~'\n" + "SimilarToToken <- ('SIMILAR' 'TO') / '~'\n" + "NotILikeOp <- '!~~*'\n" + "NotLikeOp <- '!~~'\n" + "NotSimilarToOp <- '!~'\n" + "InClause <- 'IN' InExpression\n" + "InExpression <- InExpressionList / InSelectStatement / OtherOperatorExpression\n" + "InExpressionList <- Parens(List(Expression))\n" + "InSelectStatement <- Parens(SelectStatementInternal)\n" + "BetweenClause <- 'BETWEEN' OtherOperatorExpression 'AND' OtherOperatorExpression\n" + "# LEVEL 8\n" + "OtherOperatorExpression <- BitwiseExpression (OtherOperator BitwiseExpression)*\n" + "OtherOperator <-\n" + " QualifiedOperator / AnyAllOperator / InetOperator / JsonOperator / ListOperator / StringOperator / OperatorLiteral\n" + "OperatorLiteral <- Identifier\n" + "AnyAllOperator <- AnyOp AnyOrAll\n" + "AnyOrAll <- SubqueryAny / SubqueryAll\n" + "SubqueryAny <- 'ANY'\n" + "SubqueryAll <- 'ALL'\n" + "InetOperator <- '>>=' / '<<='\n" + "JsonOperator <- '->>'\n" + "ListOperator <- '&&' / '@>' / '<@'\n" + "StringOperator <- '^@' / '||'\n" + "QualifiedOperator <- 'OPERATOR' Parens(ColIdDot* AnyOp)\n" + "AnyOp <- '!~~*' / '>>=' / '<<=' / '->>' / '!~~' / '~~*' / '~~~' / '!~' / '^@' / '||' / '&&' / '@>' / '<@' / '<=' / '>=' / '<>' / '!=' / '==' / '<<' / '>>' / '//' / '**' / '->' / '~~' / '+' / '-' / '*' / '/' / '%' / '^' / '<' / '>' / '=' / '&' / '|' / '~' / '!'\n" + "# LEVEL 9\n" + "BitwiseExpression <- AdditiveExpression (BitOperator AdditiveExpression)*\n" + "BitOperator <- '&' / '|' / '<<' / '>>'\n" + "# LEVEL 10\n" + "AdditiveExpression <- MultiplicativeExpression (Term MultiplicativeExpression)*\n" + "Term <- '+' / '-'\n" + "# LEVEL 11\n" + "MultiplicativeExpression <- ExponentiationExpression (Factor ExponentiationExpression)*\n" + "Factor <- '*' / '/' / '//' / '%'\n" + "# LEVEL 12\n" + "ExponentiationExpression <- CollateExpression (ExponentOperator CollateExpression)*\n" + "ExponentOperator <- '^' / '**'\n" + "# LEVEL 13\n" + "CollateExpression <- AtTimeZoneExpression (CollateOperator AtTimeZoneExpression)*\n" + "CollateOperator <- 'COLLATE'\n" + "# LEVEL 14\n" + "AtTimeZoneExpression <- PrefixExpression (AtTimeZoneOperator PrefixExpression)*\n" + "AtTimeZoneOperator <- 'AT' 'TIME' 'ZONE'\n" + "# LEVEL 15\n" + "PrefixExpression <- PrefixOperator* BaseExpression\n" + "PrefixOperator <- QualifiedOperator / MinusPrefixOperator / PlusPrefixOperator / TildePrefixOperator\n" + "MinusPrefixOperator <- '-'\n" + "PlusPrefixOperator <- '+'\n" + "TildePrefixOperator <- '~'\n" + "# LEVEL 16 (Highest)\n" + "BaseExpression <- SingleExpression Indirection*\n" + "Indirection <- CastOperator / DotOperator / SliceExpression / PostfixOperator\n" + "CastOperator <- '::' Type\n" + "DotOperator <- '.' (MethodExpression / ColLabel)\n" + "MethodExpression <- ColLabel Parens(DistinctOrAll? List(FunctionArgument)? OrderByClause? IgnoreOrRespectNulls?)\n" + "SliceExpression <- '[' SliceBound ']'\n" + "SliceBound <- Expression? EndSliceBound? StepSliceBound?\n" + "EndSliceBound <- ':' (Expression / '-')?\n" + "StepSliceBound <- ':' Expression?\n" + "PostfixOperator <- '!'\n" + "SpecialFunctionExpression <- CoalesceExpression / UnpackExpression / TryExpression / ColumnsExpression / ExtractExpression / LambdaExpression / NullIfExpression / PositionExpression / RowExpression / SubstringExpression / TrimExpression / OverlayExpression\n" + "CoalesceExpression <- 'COALESCE' Parens(List(Expression))\n" + "UnpackExpression <- 'UNPACK' Parens(Expression)\n" + "TryExpression <- 'TRY' Parens(Expression)\n" + "ColumnsExpression <- '*'? 'COLUMNS' Parens(Expression)\n" + "ExtractExpression <- 'EXTRACT' Parens(ExtractArgument 'FROM' Expression)\n" + "LambdaExpression <- 'LAMBDA' List(ColIdOrString) ':' Expression\n" + "NullIfExpression <- 'NULLIF' Parens(Expression ',' Expression)\n" + "PositionExpression <- 'POSITION' Parens(SingleExpression 'IN' SingleExpression)\n" + "RowExpression <- 'ROW' Parens(List(Expression)?)\n" + "SubstringExpression <- 'SUBSTRING' Parens(SubstringArguments)\n" + "SubstringArguments <- SubstringParameters / SubstringExpressionList\n" + "SubstringExpressionList <- List(Expression)\n" + "SubstringParameters <- Expression SubstringFromFor\n" + "SubstringFromFor <- SubstringFromOptionalFor / SubstringFor\n" + "SubstringFromOptionalFor <- FromExpression ForExpression?\n" + "SubstringFor <- ForExpression\n" + "TrimExpression <- 'TRIM' Parens(TrimDirection? TrimSource? List(Expression))\n" + "TrimDirection <- TrimBoth / TrimLeading / TrimTrailing\n" + "TrimBoth <- 'BOTH'\n" + "TrimLeading <- 'LEADING'\n" + "TrimTrailing <- 'TRAILING'\n" + "TrimSource <- Expression? 'FROM'\n" + "OverlayExpression <- 'OVERLAY' Parens(OverlayArguments)\n" + "OverlayArguments <- OverlayParameters / OverlayExpressionList\n" + "OverlayParameters <- Expression 'PLACING' Expression FromExpression ForExpression?\n" + "FromExpression <- 'FROM' Expression\n" + "ForExpression <- 'FOR' Expression\n" + "OverlayExpressionList <- List(Expression)\n" + "ExtractArgument <-\n" + " YearKeyword / MonthKeyword / DayKeyword / HourKeyword / MinuteKeyword / SecondKeyword /\n" + " MillisecondKeyword / MicrosecondKeyword / WeekKeyword / QuarterKeyword / DecadeKeyword /\n" + " CenturyKeyword / MillenniumKeyword / Identifier / StringLiteral\n" + "ExecuteStatement <- 'EXECUTE' Identifier TableFunctionArguments?\n" + "CreateSecretStmt <- 'SECRET' IfNotExists? SecretName? SecretStorageSpecifier? GenericCopyOptionList\n" + "SecretStorageSpecifier <- 'IN' Identifier\n" + "SecretName <- ColId\n" + "CreateViewStmt <- CreateRecursive? 'VIEW' IfNotExists? QualifiedName InsertColumnList? WithList? 'AS' SelectStatementInternal\n" + "CreateRecursive <- 'RECURSIVE'\n" + "DescribeStatement <- ShowTables / ShowSelect / ShowAllTables / ShowQualifiedName\n" + "ShowSelect <- ShowOrDescribeOrSummarize SelectStatementInternal\n" + "ShowAllTables <- ShowOrDescribe 'ALL' 'TABLES'\n" + "ShowQualifiedName <- ShowOrDescribeOrSummarize DescribeTarget?\n" + "ShowTables <- ShowOrDescribe 'TABLES' 'FROM' QualifiedName\n" + "DescribeTarget <- DescribeBaseTableName / DescribeStringLiteral\n" + "DescribeBaseTableName <- BaseTableName\n" + "DescribeStringLiteral <- StringLiteral\n" + "ShowOrDescribeOrSummarize <- ShowOrDescribe / Summarize\n" + "Summarize <- SummarizeRule\n" + "SummarizeRule <- 'SUMMARIZE'\n" + "ShowOrDescribe <- ShowRule / DescribeRule\n" + "ShowRule <- 'SHOW'\n" + "DescribeRule <- DescribeLongRule / DescRule\n" + "DescribeLongRule <- 'DESCRIBE'\n" + "DescRule <- 'DESC'\n" + "VacuumStatement <- 'VACUUM' VacuumOptions? AnalyzeTarget?\n" + "VacuumOptions <- VacuumParensOptions / VacuumLegacyOptions\n" + "VacuumParensOptions <- Parens(List(VacuumOption))\n" + "VacuumLegacyOptions <- OptFull? OptFreeze? OptVerbose? OptAnalyze?\n" + "VacuumOption <- OptAnalyze / OptFreeze / OptFull / OptVerbose / Identifier\n" + "OptAnalyze <- 'ANALYZE'\n" + "OptFull <- 'FULL'\n" + "OptFreeze <- 'FREEZE'\n" + "OptVerbose <- 'VERBOSE'\n" + "NameList <- Parens(List(ColId))\n" + "MergeIntoStatement <- WithClause? 'MERGE' 'INTO' TargetOptAlias MergeIntoUsingClause JoinQualifier MergeMatch+ ReturningClause?\n" + "MergeIntoUsingClause <- 'USING' TableRef\n" + "MergeMatch <- MatchedClause / NotMatchedClause\n" + "MatchedClause <- 'WHEN' 'MATCHED' AndExpression? 'THEN' MatchedClauseAction\n" + "MatchedClauseAction <- UpdateMatchClause / DeleteMatchClause / InsertMatchClause / DoNothingMatchClause / ErrorMatchClause\n" + "UpdateMatchClause <- 'UPDATE' UpdateMatchInfo?\n" + "UpdateMatchInfo <- UpdateMatchSetAction / UpdateByNameOrPosition\n" + "UpdateMatchSetAction <- UpdateMatchSetClause\n" + "UpdateByNameOrPosition <- ByNameOrPosition\n" + "DeleteMatchClause <- 'DELETE'\n" + "InsertMatchClause <- 'INSERT' InsertMatchInfo?\n" + "InsertMatchInfo <- InsertValuesList / InsertDefaultValues / InsertByNameOrPosition\n" + "InsertDefaultValues <- 'DEFAULT' 'VALUES'\n" + "InsertByNameOrPosition <- ByNameOrPosition? '*'?\n" + "InsertValuesList <- InsertColumnList? 'VALUES' Parens(List(Expression))\n" + "DoNothingMatchClause <- 'DO' 'NOTHING'\n" + "ErrorMatchClause <- 'ERROR' Expression?\n" + "UpdateMatchSetClause <- 'SET' UpdateMatchSetInfo\n" + "UpdateMatchSetInfo <- UpdateSetClause / StarSymbol\n" + "AndExpression <- 'AND' Expression\n" + "NotMatchedClause <- 'WHEN' 'NOT' 'MATCHED' BySourceOrTarget? AndExpression? 'THEN' MatchedClauseAction\n" + "BySourceOrTarget <- BySource / ByTarget\n" + "BySource <- 'BY' 'SOURCE'\n" + "ByTarget <- 'BY' 'TARGET'\n" + "PragmaStatement <- 'PRAGMA' PragmaAssignOrFunction\n" + "PragmaAssignOrFunction <- PragmaAssign / PragmaFunction\n" + "PragmaAssign <- SettingName '=' VariableList\n" + "PragmaFunction <- PragmaName PragmaParameters?\n" + "PragmaParameters <- Parens(List(Expression))\n" + "DeallocateStatement <- 'DEALLOCATE' DeallocatePrepare? Identifier\n" + "DeallocatePrepare <- 'PREPARE'\n" + "PrepareStatement <- 'PREPARE' Identifier TypeList? 'AS' Statement\n" + "TypeList <- Parens(List(Type))\n" + "CreateStatement <- 'CREATE' OrReplace? Temporary? CreateStatementVariation\n" + "CreateStatementVariation <- CreateTableStmt / CreateMacroStmt / CreateSequenceStmt / CreateTypeStmt / CreateSchemaStmt / CreateViewStmt / CreateIndexStmt / CreateSecretStmt / CreateTriggerStmt\n" + "OrReplace <- 'OR' 'REPLACE'\n" + "Temporary <- Persistent / TempPersistent / TemporaryPersistent\n" + "Persistent <- 'PERSISTENT'\n" + "TempPersistent <- 'TEMP'\n" + "TemporaryPersistent <- 'TEMPORARY'\n" + "CreateTableStmt <- 'TABLE' IfNotExists? QualifiedName CreateTableDefinition CommitAction?\n" + "CreateTableDefinition <- CreateTableAs / CreateColumnList\n" + "CreateTableAs <- IdentifierList? PartitionSortedOptions? WithList? 'AS' Statement WithData?\n" + "PartitionSortedOptions <- PartitionOptSortedOptions / SortedOptPartitionOptions\n" + "PartitionOptSortedOptions <- PartitionOptions SortedOptions?\n" + "SortedOptPartitionOptions <- SortedOptions PartitionOptions?\n" + "PartitionOptions <- 'PARTITIONED' 'BY' Parens(List(Expression))\n" + "SortedOptions <- 'SORTED' 'BY' Parens(List(Expression))\n" + "WithData <- WithDataOnly / WithNoData\n" + "WithDataOnly <- 'WITH' 'DATA'\n" + "WithNoData <- 'WITH' 'NO' 'DATA'\n" + "IdentifierList <- Parens(List(Identifier))\n" + "CreateColumnList <- Parens(CreateTableColumnList?) PartitionSortedOptions? WithList?\n" + "IfNotExists <- 'IF' 'NOT' 'EXISTS'\n" + "QualifiedName <- CatalogReservedSchemaIdentifier / SchemaReservedIdentifierOrStringLiteral / IdentifierOrStringLiteral\n" + "SchemaReservedIdentifierOrStringLiteral <- SchemaQualification ReservedIdentifierOrStringLiteral\n" + "CatalogReservedSchemaIdentifier <- CatalogQualification ReservedSchemaQualification ReservedIdentifierOrStringLiteral\n" + "IdentifierOrStringLiteral <- Identifier / StringLiteral\n" + "ReservedIdentifierOrStringLiteral <- ReservedIdentifier / StringLiteral\n" + "CatalogQualification <- CatalogName '.'\n" + "SchemaQualification <- SchemaName '.'\n" + "ReservedSchemaQualification <- ReservedSchemaName '.'\n" + "TableQualification <- TableName '.'\n" + "ReservedTableQualification <- ReservedTableName '.'\n" + "CreateTableColumnList <- List(CreateTableColumnElement)\n" + "CreateTableColumnElement <- CreateTableColumnDefinition / CreateTableConstraint\n" + "CreateTableColumnDefinition <- ColumnDefinition\n" + "CreateTableConstraint <- TopLevelConstraint\n" + "ColumnDefinition <- DottedIdentifier Type? GeneratedColumn? ConstraintNameClause? ColumnConstraint*\n" + "ColumnConstraint <- NotNullConstraint / UniqueConstraint / PrimaryKeyConstraint / DefaultValue / CheckConstraint / ForeignKeyConstraint / ColumnCollation / ColumnCompression\n" + "NotNullConstraint <- NullConstraint / NotNullColumnConstraint\n" + "NullConstraint <- 'NULL'\n" + "NotNullColumnConstraint <- 'NOT' 'NULL'\n" + "UniqueConstraint <- 'UNIQUE'\n" + "PrimaryKeyConstraint <- 'PRIMARY' 'KEY'\n" + "DefaultValue <- 'DEFAULT' ColumnDefaultExpr\n" + "CheckConstraint <- 'CHECK' Parens(Expression)\n" + "ForeignKeyConstraint <- 'REFERENCES' BaseTableName Parens(ColumnList)? KeyActions\n" + "ColumnCollation <- 'COLLATE' DottedIdentifier\n" + "ColumnCompression <- 'USING' 'COMPRESSION' ColIdOrString\n" + "KeyActions <- UpdateAction? DeleteAction?\n" + "UpdateAction <- 'ON' 'UPDATE' KeyAction\n" + "DeleteAction <- 'ON' 'DELETE' KeyAction\n" + "KeyAction <- NoKeyAction / RestrictKeyAction / CascadeKeyAction / SetNullKeyAction / SetDefaultKeyAction\n" + "NoKeyAction <- 'NO' 'ACTION'\n" + "RestrictKeyAction <- 'RESTRICT'\n" + "CascadeKeyAction <- 'CASCADE'\n" + "SetNullKeyAction <- 'SET' 'NULL'\n" + "SetDefaultKeyAction <- 'SET' 'DEFAULT'\n" + "TopLevelConstraint <- ConstraintNameClause? TopLevelConstraintList\n" + "TopLevelConstraintList <- TopPrimaryKeyConstraint / CheckConstraint / TopUniqueConstraint / TopForeignKeyConstraint\n" + "ConstraintNameClause <- 'CONSTRAINT' Identifier\n" + "TopPrimaryKeyConstraint <- 'PRIMARY' 'KEY' ColumnIdList\n" + "TopUniqueConstraint <- 'UNIQUE' ColumnIdList\n" + "TopForeignKeyConstraint <- 'FOREIGN' 'KEY' ColumnIdList ForeignKeyConstraint\n" + "ColumnIdList <- Parens(List(ColId))\n" + "PlainIdentifier <- !ReservedKeyword <[a-z_]i[a-z0-9_]i*>\n" + "QuotedIdentifier <- '\"' [^\"]* '\"'\n" + "DottedIdentifier <- Identifier DotColLabel*\n" + "DotColLabel <- '.' ColLabel\n" + "Identifier <- QuotedIdentifier / PlainIdentifier\n" + "ColId <- UnreservedKeyword / ColumnNameKeyword / Identifier\n" + "ColIdOrString <- ColId / StringLiteral\n" + "TypeFuncName <- UnreservedKeyword / TypeNameKeyword / FuncNameKeyword / Identifier\n" + "TypeName <- UnreservedKeyword / TypeNameKeyword / Identifier\n" + "ColLabel <- ReservedKeyword / UnreservedKeyword / ColumnNameKeyword / FuncNameKeyword / TypeNameKeyword / Identifier\n" + "ColLabelOrString <- ColLabel / StringLiteral\n" + "GeneratedColumn <- Generated? 'AS' Parens(Expression) GeneratedColumnType?\n" + "Generated <- 'GENERATED' AlwaysOrByDefault?\n" + "AlwaysOrByDefault <- 'ALWAYS' / ('BY' 'DEFAULT')\n" + "GeneratedColumnType <- VirtualGeneratedColumn / StoredGeneratedColumn\n" + "CommitAction <- 'ON' 'COMMIT' PreserveOrDelete 'ROWS'\n" + "PreserveOrDelete <- PreserveRows / DeleteRows\n" + "PreserveRows <- 'PRESERVE'\n" + "DeleteRows <- 'DELETE'\n" + "VirtualGeneratedColumn <- 'VIRTUAL'\n" + "StoredGeneratedColumn <- 'STORED'\n" + "CreateIndexStmt <- UniqueIndex? 'INDEX' IfNotExists? IndexName? 'ON' BaseTableName InsertColumnList? IndexType? Parens(List(IndexElement))? WithList? WhereClause?\n" + "WithList <- 'WITH' RelOptionOrOids\n" + "RelOptionOrOids <- RelOptionList / Oids\n" + "RelOptionList <- Parens(List(RelOption))\n" + "Oids <- WithOrWithoutOids 'OIDS'\n" + "WithOrWithoutOids <- WithOids / WithoutOids\n" + "WithOids <- 'WITH'\n" + "WithoutOids <- 'WITHOUT'\n" + "IndexElement <- Expression DescOrAsc? NullsFirstOrLast?\n" + "UniqueIndex <- 'UNIQUE'\n" + "IndexType <- 'USING' Identifier\n" + "RelOption <- RelOptionName RelOptionArgumentOpt?\n" + "RelOptionName <- DottedIdentifierString / StringLiteral\n" + "DottedIdentifierString <- DottedIdentifier\n" + "RelOptionArgumentOpt <- '=' DefArg\n" + "DefArg <- DefArgNull / DefArgKeyword / DefArgStringLiteral / NumberLiteral / NoneLiteral / Expression\n" + "DefArgNull <- NullLiteral\n" + "DefArgKeyword <- ReservedKeyword\n" + "DefArgStringLiteral <- StringLiteral\n" + "NoneLiteral <- 'NONE'\n" + "LoadStatement <- 'LOAD' ColIdOrString ExtensionAlias?\n" + "ExtensionAlias <- 'AS' Identifier\n" + "InstallStatement <- 'FORCE'? 'INSTALL' IdentifierOrStringLiteral FromSource? VersionNumber?\n" + "UpdateExtensionsStatement <- 'UPDATE' 'EXTENSIONS' Parens(List(Identifier))?\n" + "FromSource <- FromSourceIdentifier / FromSourceString\n" + "FromSourceIdentifier <- 'FROM' Identifier\n" + "FromSourceString <- 'FROM' StringLiteral\n" + "VersionNumber <- 'VERSION' IdentifierOrStringLiteral\n" + "DropStatement <- 'DROP' DropEntries DropBehavior?\n" + "DropEntries <-\n" + " DropTable /\n" + " DropTableFunction /\n" + " DropFunction /\n" + " DropSchema /\n" + " DropIndex /\n" + " DropSequence /\n" + " DropCollation /\n" + " DropType /\n" + " DropSecret /\n" + " DropTrigger\n" + "DropTrigger <- 'TRIGGER' IfExists? TriggerName 'ON' BaseTableName\n" + "DropTable <- TableOrView IfExists? List(BaseTableName)\n" + "DropTableFunction <- CommentMacroTable IfExists? List(TableFunctionName)\n" + "DropFunction <- FunctionTypeMacro IfExists? List(FunctionIdentifier)\n" + "DropSchema <- 'SCHEMA' IfExists? List(QualifiedSchemaName)\n" + "DropIndex <- 'INDEX' IfExists? List(QualifiedIndexName)\n" + "QualifiedIndexName <- CatalogReservedSchemaIndex / SchemaReservedIndex / QualifiedIndexNameString\n" + "QualifiedIndexNameString <- IndexName\n" + "SchemaReservedIndex <- SchemaQualification ReservedIndexName\n" + "CatalogReservedSchemaIndex <- CatalogQualification ReservedSchemaQualification ReservedIndexName\n" + "DropSequence <- 'SEQUENCE' IfExists? List(QualifiedSequenceName)\n" + "DropCollation <- 'COLLATION' IfExists? List(CollationName)\n" + "DropType <- 'TYPE' IfExists? List(QualifiedTypeName)\n" + "DropSecret <- Temporary? 'SECRET' IfExists? SecretName DropSecretStorage?\n" + "TableOrView <- CommentTable / CommentView / MaterializedViewEntry\n" + "MaterializedViewEntry <- 'MATERIALIZED' 'VIEW'\n" + "FunctionTypeMacro <- FunctionTypeMacroKeyword / FunctionTypeFunction\n" + "FunctionTypeMacroKeyword <- 'MACRO'\n" + "FunctionTypeFunction <- 'FUNCTION'\n" + "DropBehavior <- CascadeDropBehavior / RestrictDropBehavior\n" + "CascadeDropBehavior <- 'CASCADE'\n" + "RestrictDropBehavior <- 'RESTRICT'\n" + "IfExists <- 'IF' 'EXISTS'\n" + "QualifiedSchemaName <- CatalogReservedSchema / QualifiedSchemaNameString\n" + "QualifiedSchemaNameString <- SchemaName\n" + "CatalogReservedSchema <- CatalogQualification ReservedSchemaName\n" + "DropSecretStorage <- 'FROM' Identifier\n" + "UpdateStatement <- WithClause? 'UPDATE' UpdateTarget UpdateSetClause FromClause? WhereClause? ReturningClause?\n" + "UpdateTarget <- BaseTableSet / BaseTableAliasSet\n" + "BaseTableSet <- BaseTableName 'SET'\n" + "BaseTableAliasSet <- BaseTableName UpdateAlias? 'SET'\n" + "UpdateAlias <- 'AS'? ColId\n" + "UpdateSetClause <- UpdateSetElementList / UpdateSetTuple\n" + "UpdateSetTuple <- Parens(List(ColumnName)) '=' Expression\n" + "UpdateSetElementList <- List(UpdateSetElement)\n" + "UpdateSetElement <- UpdateSetColumnTarget '=' Expression\n" + "UpdateSetColumnTarget <- ColumnName DotIdentifier*\n" + "InsertStatement <- WithClause? 'INSERT' OrAction? 'INTO' InsertTarget ByNameOrPosition? InsertColumnList? InsertValues OnConflictClause? ReturningClause?\n" + "OrAction <- InsertOrReplace / InsertOrIgnore\n" + "InsertOrReplace <- 'OR' 'REPLACE'\n" + "InsertOrIgnore <- 'OR' 'IGNORE'\n" + "ByNameOrPosition <- InsertByNameOrder / InsertByPositionOrder\n" + "InsertByNameOrder <- 'BY' InsertByName\n" + "InsertByPositionOrder <- 'BY' InsertByPosition\n" + "InsertByName <- 'NAME'\n" + "InsertByPosition <- 'POSITION'\n" + "InsertTarget <- BaseTableName InsertAlias?\n" + "InsertAlias <- 'AS' Identifier\n" + "ColumnList <- List(ColId)\n" + "InsertColumnList <- Parens(ColumnList)\n" + "InsertValues <- SelectInsertValues / DefaultValues\n" + "SelectInsertValues <- SelectStatementInternal\n" + "DefaultValues <- 'DEFAULT' 'VALUES'\n" + "OnConflictClause <- 'ON' 'CONFLICT' OnConflictTarget? OnConflictAction\n" + "OnConflictTarget <- OnConflictExpressionTarget / OnConflictIndexTarget\n" + "OnConflictExpressionTarget <- ColumnIdList WhereClause?\n" + "OnConflictIndexTarget <- 'ON' 'CONSTRAINT' ConstraintName\n" + "OnConflictAction <- OnConflictUpdate / OnConflictNothing\n" + "OnConflictUpdate <- 'DO' 'UPDATE' 'SET' UpdateSetClause WhereClause?\n" + "OnConflictNothing <- 'DO' 'NOTHING'\n" + "ReturningClause <- 'RETURNING' TargetList\n" + "CreateSchemaStmt <- 'SCHEMA' IfNotExists? QualifiedName\n" + "SelectStatement <- SelectStatementInternal\n" + "SelectStatementInternal <- WithClause? SelectSetOpChain ResultModifiers?\n" + "SelectSetOpChain <- IntersectChain (SetopClause IntersectChain)*\n" + "IntersectChain <- SelectAtom (SetIntersectClause SelectAtom)*\n" + "SetIntersectClause <- 'INTERSECT' DistinctOrAll?\n" + "SelectAtom <- SelectParens / SelectStatementType\n" + "SelectParens <- Parens(SelectStatementInternal)\n" + "SetopClause <- SetopType DistinctOrAll? ByName?\n" + "SetopType <- SetopUnion / SetopExcept\n" + "SetopUnion <- 'UNION'\n" + "SetopExcept <- 'EXCEPT'\n" + "ByName <- 'BY' 'NAME'\n" + "SelectStatementType <- OptionalParensSimpleSelect / ValuesClause / DescribeStatement / TableStatement / PivotStatement / UnpivotStatement\n" + "ResultModifiers <- OrderByClause? LimitOffset?\n" + "LimitOffset <- LimitOffsetClause / OffsetLimitClause\n" + "LimitOffsetClause <- LimitClause OffsetClause?\n" + "OffsetLimitClause <- OffsetClause LimitClause?\n" + "TableStatement <- 'TABLE' BaseTableName\n" + "OptionalParensSimpleSelect <- SimpleSelectParens / SimpleSelect\n" + "SimpleSelectParens <- Parens(SimpleSelect)\n" + "SimpleSelect <- SelectFrom WhereClause? GroupByClause? HavingClause? WindowClause? QualifyClause? SampleClause?\n" + "SelectFrom <- SelectFromClause / FromSelectClause\n" + "SelectFromClause <- SelectClause FromClause?\n" + "FromSelectClause <- FromClause SelectClause?\n" + "WithStatement <- ColIdOrString InsertColumnList? UsingKey? 'AS' Materialized? CTEBody\n" + "CTEBody <- Parens(CTEBodyContent)\n" + "CTEBodyContent <- SelectStatementInternal / Statement\n" + "UsingKey <- 'USING' 'KEY' Parens(TargetList)\n" + "Materialized <- 'NOT'? 'MATERIALIZED'\n" + "WithClause <- 'WITH' Recursive? List(WithStatement)\n" + "Recursive <- 'RECURSIVE'\n" + "SelectClause <- 'SELECT' DistinctClause? TargetList?\n" + "TargetList <- List(AliasedExpression)\n" + "ColumnAliases <- Parens(List(ColIdOrString))\n" + "DistinctClause <- DistinctOn / DistinctAll\n" + "DistinctAll <- 'ALL'\n" + "DistinctOn <- 'DISTINCT' DistinctOnTargets?\n" + "DistinctOnTargets <- 'ON' Parens(List(Expression))\n" + "InnerTableRef <- ValuesRef / TableFunction / TableSubquery / BaseTableRef / ParensTableRef\n" + "TableRef <- InnerTableRef JoinOrPivot*\n" + "TableSubquery <- Lateral? SubqueryReference TableAlias?\n" + "BaseTableRef <- TableAliasColon? BaseTableName TableAlias? AtClause? SampleClause?\n" + "TableAliasColon <- ColIdOrString ':'\n" + "ValuesRef <- ValuesClause TableAlias?\n" + "ParensTableRef <- TableAliasColon? Parens(TableRef) TableAlias? SampleClause?\n" + "JoinOrPivot <- JoinClause / TablePivotClause / TableUnpivotClause\n" + "TablePivotClause <- 'PIVOT' Parens(TargetList 'FOR' PivotValueList+ PivotGroupByList?) TableAlias?\n" + "PivotGroupByList <- 'GROUP' 'BY' List(ColIdOrString)\n" + "TableUnpivotClause <- 'UNPIVOT' IncludeOrExcludeNulls? Parens(UnpivotHeader 'FOR' UnpivotValueList+) TableAlias?\n" + "PivotHeader <- BaseExpression\n" + "PivotValueList <- PivotHeader 'IN' (Identifier / PivotTargetList)\n" + "UnpivotValueList <- UnpivotHeader 'IN' UnpivotTargetList\n" + "PivotTargetList <- Parens(TargetList)\n" + "UnpivotTargetList <- Parens(TargetList)\n" + "Lateral <- 'LATERAL'\n" + "BaseTableName <- CatalogReservedSchemaTable / SchemaReservedTable / TableName\n" + "SchemaReservedTable <- SchemaQualification ReservedTableName\n" + "CatalogReservedSchemaTable <- CatalogQualification ReservedSchemaQualification ReservedTableName\n" + "TableFunction <- TableFunctionLateralOpt / TableFunctionAliasColon\n" + "TableFunctionLateralOpt <- Lateral? QualifiedTableFunction TableFunctionArguments WithOrdinality? TableAlias?\n" + "TableFunctionAliasColon <- TableAliasColon QualifiedTableFunction TableFunctionArguments WithOrdinality? SampleClause?\n" + "WithOrdinality <- 'WITH' 'ORDINALITY'\n" + "QualifiedTableFunction <- CatalogQualification? SchemaQualification? TableFunctionName\n" + "TableFunctionArguments <- Parens(List(FunctionArgument)?)\n" + "FunctionArgument <- NamedParameter / Expression\n" + "NamedParameter <- TypeFuncName Type? NamedParameterAssignment Expression\n" + "NamedParameterAssignment <- ':=' / '=>'\n" + "TableAlias <- TableAliasAs / TableAliasWithoutAs\n" + "TableAliasAs <- 'AS' IdentifierOrStringLiteral ColumnAliases?\n" + "TableAliasWithoutAs <- Identifier ColumnAliases?\n" + "AtClause <- 'AT' Parens(AtSpecifier)\n" + "AtSpecifier <- AtUnit '=>' Expression\n" + "AtUnit <- 'VERSION' / 'TIMESTAMP'\n" + "JoinClause <- RegularJoinClause / JoinWithoutOnClause\n" + "RegularJoinClause <- 'ASOF'? JoinType? 'JOIN' TableRef JoinQualifier\n" + "JoinWithoutOnClause <- JoinPrefix 'JOIN' TableRef\n" + "JoinQualifier <- OnClause / UsingClause\n" + "OnClause <- 'ON' Expression\n" + "UsingClause <- 'USING' Parens(List(ColumnName))\n" + "JoinType <- FullJoin / LeftJoin / RightJoin / SemiJoin / AntiJoin / InnerJoin\n" + "JoinPrefix <- CrossJoinPrefix / NaturalJoinPrefix / PositionalJoinPrefix\n" + "CrossJoinPrefix <- 'CROSS'\n" + "NaturalJoinPrefix <- 'NATURAL' JoinType?\n" + "PositionalJoinPrefix <- 'POSITIONAL'\n" + "FullJoin <- 'FULL' 'OUTER'?\n" + "LeftJoin <- 'LEFT' 'OUTER'?\n" + "RightJoin <- 'RIGHT' 'OUTER'?\n" + "SemiJoin <- 'SEMI'\n" + "AntiJoin <- 'ANTI'\n" + "InnerJoin <- 'INNER'\n" + "FromClause <- 'FROM' List(TableRef)\n" + "WhereClause <- 'WHERE' Expression\n" + "GroupByClause <- 'GROUP' 'BY' GroupByExpressions\n" + "HavingClause <- 'HAVING' Expression\n" + "QualifyClause <- 'QUALIFY' Expression\n" + "SampleClause <- (TableSample / UsingSample) SampleEntry\n" + "UsingSample <- 'USING' 'SAMPLE'\n" + "TableSample <- 'TABLESAMPLE'\n" + "WindowClause <- 'WINDOW' List(WindowDefinition)\n" + "WindowDefinition <- Identifier 'AS' WindowFrameDefinition\n" + "SampleEntry <- SampleEntryFunction / SampleEntryCount\n" + "SampleEntryCount <- SampleCount Parens(SampleProperties)?\n" + "SampleEntryFunction <- SampleFunction? Parens(SampleCount) RepeatableSample?\n" + "SampleFunction <- ColId\n" + "SampleProperties <- ColId (',' SampleSeed)?\n" + "RepeatableSample <- 'REPEATABLE' Parens(SampleSeed)\n" + "SampleSeed <- NumberLiteral\n" + "SampleCount <- SampleValue SampleUnit?\n" + "SampleValue <- NumberLiteral / Parameter\n" + "SampleUnit <- SamplePercentage / SampleRows\n" + "SamplePercentage <- '%' / 'PERCENT'\n" + "SampleRows <- 'ROWS'\n" + "GroupByExpressions <- GroupByList / GroupByAll\n" + "GroupByAll <- 'ALL'\n" + "GroupByList <- List(GroupByExpression)\n" + "GroupByExpression <- EmptyGroupingItem / CubeOrRollupClause / GroupingSetsClause / Expression\n" + "EmptyGroupingItem <- '(' ')'\n" + "CubeOrRollupClause <- CubeOrRollup Parens(List(Expression)?)\n" + "CubeOrRollup <- 'CUBE' / 'ROLLUP'\n" + "GroupingSetsClause <- 'GROUPING' 'SETS' Parens(GroupByList)\n" + "SubqueryReference <- Parens(SelectStatementInternal)\n" + "OrderByExpression <- Expression DescOrAsc? NullsFirstOrLast?\n" + "DescOrAsc <- DescendingOrder / AscendingOrder\n" + "DescendingOrder <- 'DESC' / 'DESCENDING'\n" + "AscendingOrder <- 'ASC' / 'ASCENDING'\n" + "NullsFirstOrLast <- NullsFirst / NullsLast\n" + "NullsFirst <- 'NULLS' 'FIRST'\n" + "NullsLast <- 'NULLS' 'LAST'\n" + "OrderByClause <- 'ORDER' 'BY' OrderByExpressions\n" + "OrderByExpressions <- OrderByAll / OrderByExpressionList\n" + "OrderByExpressionList <- List(OrderByExpression)\n" + "OrderByAll <- 'ALL' DescOrAsc? NullsFirstOrLast?\n" + "LimitClause <- 'LIMIT' LimitValue\n" + "OffsetClause <- 'OFFSET' OffsetValue\n" + "OffsetValue <- Expression RowOrRows?\n" + "RowOrRows <- 'ROW' / 'ROWS'\n" + "LimitValue <- LimitAll / LimitLiteralPercent / LimitExpression\n" + "LimitAll <- 'ALL'\n" + "LimitLiteralPercent <- NumberLiteral 'PERCENT'\n" + "LimitExpression <- Expression '%'?\n" + "AliasedExpression <- ColIdExpression / ExpressionAsCollabel / ExpressionOptIdentifier\n" + "ColIdExpression <- ColId ':' Expression\n" + "ExpressionAsCollabel <- Expression 'AS' ColLabelOrString\n" + "ExpressionOptIdentifier <- Expression Identifier?\n" + "ValuesClause <- 'VALUES' List(ValuesExpressions)\n" + "ValuesExpressions <- Parens(List(Expression))\n" + "TransactionStatement <- BeginTransaction / RollbackTransaction / CommitTransaction\n" + "BeginTransaction <- StartOrBegin Transaction? ReadOrWrite?\n" + "RollbackTransaction <- AbortOrRollback Transaction?\n" + "CommitTransaction <- CommitOrEnd Transaction?\n" + "StartOrBegin <- 'START' / 'BEGIN'\n" + "Transaction <- 'WORK' / 'TRANSACTION'\n" + "ReadOrWrite <- 'READ' ReadOnlyOrReadWrite\n" + "ReadOnlyOrReadWrite <- ReadOnly / ReadWrite\n" + "ReadOnly <- 'ONLY'\n" + "ReadWrite <- 'WRITE'\n" + "AbortOrRollback <- 'ABORT' / 'ROLLBACK'\n" + "CommitOrEnd <- 'COMMIT' / 'END'\n" + "DeleteStatement <- WithClause? 'DELETE' 'FROM' TargetOptAlias DeleteUsingClause? WhereClause? ReturningClause?\n" + "TruncateStatement <- 'TRUNCATE' 'TABLE'? BaseTableName\n" + "TargetOptAlias <- BaseTableName 'AS'? ColId?\n" + "DeleteUsingClause <- 'USING' List(TableRef)\n" + "ConnectStatement <- 'CONNECT' SessionTarget?\n" + "DisconnectStatement <- 'DISCONNECT'\n" + "SessionTarget <- 'LOCAL' / StringLiteral / CatalogName\n" + "CreateTypeStmt <- 'TYPE' IfNotExists? QualifiedName 'AS' CreateType\n" + "CreateType <- EnumSelectType / EnumStringLiteralList / CreateTypeFromType\n" + "CreateTypeFromType <- Type\n" + "EnumSelectType <- 'ENUM' Parens(SelectStatementInternal)\n" + "EnumStringLiteralList <- 'ENUM' Parens(List(StringLiteral)?)\n" + "SetStatement <- 'SET' SetAssignmentOrTimeZone\n" + "SetAssignmentOrTimeZone <- StandardAssignment / SetTimeZone\n" + "ResetStatement <- 'RESET' SetVariableOrSetting\n" + "StandardAssignment <- SetVariableOrSetting SetAssignment\n" + "SetVariableOrSetting <- SetVariable / SetSetting\n" + "SetTimeZone <- 'TIME' 'ZONE' ZoneValue\n" + "ZoneValue <- ZoneIntervalWithPrecision / ZoneIntervalWithInterval / ZoneLocal / ZoneDefault / ZoneStringLiteral / ZoneIdentifier / NumberLiteral\n" + "ZoneLocal <- 'LOCAL'\n" + "ZoneDefault <- 'DEFAULT'\n" + "ZoneStringLiteral <- StringLiteral\n" + "ZoneIdentifier <- Identifier\n" + "ZoneIntervalWithInterval <- 'INTERVAL' StringLiteral Interval?\n" + "ZoneIntervalWithPrecision <- 'INTERVAL' Parens(NumberLiteral) StringLiteral\n" + "SetSetting <- SettingScope? SettingName\n" + "SetVariable <- VariableScope Identifier\n" + "VariableScope <- 'VARIABLE'\n" + "SettingScope <- LocalScope / SessionScope / GlobalScope\n" + "LocalScope <- 'LOCAL'\n" + "SessionScope <- 'SESSION'\n" + "GlobalScope <- 'GLOBAL'\n" + "SetAssignment <- VariableAssign VariableList\n" + "VariableAssign <- '=' / 'TO'\n" + "VariableList <- List(Expression)\n" + "ExportStatement <- 'EXPORT' 'DATABASE' ExportSource? StringLiteral GenericCopyOptionList?\n" + "ExportSource <- CatalogName 'TO'\n" + "ImportStatement <- 'IMPORT' 'DATABASE' StringLiteral\n" + "CheckpointStatement <- CheckpointForce? 'CHECKPOINT' CatalogName?\n" + "CheckpointForce <- 'FORCE'\n" + "CopyStatement <- 'COPY' CopyVariations\n" + "CopyVariations <- CopyTable / CopySelect / CopyFromDatabase\n" + "CopyTable <- BaseTableName InsertColumnList? FromOrTo CopyFileName CopyOptions?\n" + "FromOrTo <- CopyFrom / CopyTo\n" + "CopyFrom <- 'FROM'\n" + "CopyTo <- 'TO'\n" + "CopySelect <- Parens(SelectStatementInternal) 'TO' CopyFileName CopyOptions?\n" + "CopyFileName <- CopyFileNameExpression / CopyFileNameStringLiteral / CopyFileNameIdentifier / CopyFileNameIdentifierColId\n" + "CopyFileNameExpression <- Parameter / ParensExpression\n" + "CopyFileNameStringLiteral <- StringLiteral\n" + "CopyFileNameIdentifier <- Identifier\n" + "CopyFileNameIdentifierColId <- IdentifierColId\n" + "IdentifierColId <- Identifier '.' ColId\n" + "CopyOptions <- 'WITH'? CopyOptionList\n" + "CopyOptionList <- GenericCopyOptionList / SpecializedOptionList\n" + "SpecializedOptionList <- SpecializedOption*\n" + "SpecializedOption <- SingleOption / NullAsOption / DelimiterAsOption / EscapeAsOption /\n" + " EncodingOption / QuoteAsOption / ForceQuoteOption / PartitionByOption / ForceNullOption\n" + "SingleOption <- BinaryOption / FreezeOption / OidsOption / CsvOption / HeaderOption\n" + "BinaryOption <- 'BINARY'\n" + "FreezeOption <- 'FREEZE'\n" + "OidsOption <- 'OIDS'\n" + "CsvOption <- 'CSV'\n" + "HeaderOption <- 'HEADER'\n" + "NullAsOption <- 'NULL' 'AS'? StringLiteral\n" + "DelimiterAsOption <- 'DELIMITER' 'AS'? StringLiteral\n" + "QuoteAsOption <- 'QUOTE' 'AS'? StringLiteral\n" + "EscapeAsOption <- 'ESCAPE' 'AS'? StringLiteral\n" + "EncodingOption <- 'ENCODING' StringLiteral\n" + "ForceQuoteOption <- ForceQuote? 'QUOTE' StarSymbolColumnList\n" + "StarSymbolColumnList <- StarSymbol / ColumnList\n" + "ForceQuote <- 'FORCE'\n" + "PartitionByOption <- 'PARTITION' 'BY' StarSymbolColumnList\n" + "ForceNullOption <- 'FORCE' ForceNotNull? 'NULL' ColumnList\n" + "ForceNotNull <- 'NOT'\n" + "StarSymbol <- '*'\n" + "GenericCopyOptionList <- Parens(List(GenericCopyOption))\n" + "GenericCopyOption <- CopyOptionName GenericCopyOptionValue?\n" + "GenericCopyOptionValue <- GenericCopyOptionOrderList / GenericCopyOptionExpression\n" + "GenericCopyOptionOrderList <- GenericCopyOptionParenthesizedExpressionList\n" + "GenericCopyOptionExpression <- Expression\n" + "GenericCopyOptionParenthesizedExpressionList <- Parens(OrderByExpressionList)\n" + "CopyFromDatabase <- CopyFromDatabaseWithFlag / CopyFromDatabaseWithoutFlag\n" + "CopyFromDatabaseWithFlag <- 'FROM' 'DATABASE' ColId 'TO' ColId CopyDatabaseFlag\n" + "CopyFromDatabaseWithoutFlag <- 'FROM' 'DATABASE' ColId 'TO' ColId\n" + "CopyDatabaseFlag <- Parens(SchemaOrData)\n" + "SchemaOrData <- CopySchema / CopyData\n" + "CopySchema <- 'SCHEMA'\n" + "CopyData <- 'DATA'\n" + "AlterStatement <- 'ALTER' AlterOptions\n" + "AlterOptions <- AlterTableStmt / AlterViewStmt / AlterSequenceStmt / AlterDatabaseStmt / AlterSchemaStmt\n" + "AlterTableStmt <- 'TABLE' IfExists? BaseTableName List(AlterTableOptions)\n" + "AlterSchemaStmt <- 'SCHEMA' IfExists? QualifiedName RenameAlter\n" + "AlterTableOptions <- AddColumn / DropColumn / AlterColumn / AddConstraint / ChangeNullability /\n" + " RenameColumn / RenameAlter / SetPartitionedBy / ResetPartitionedBy / SetSortedBy / ResetSortedBy / SetOptions / ResetOptions\n" + "AddConstraint <- 'ADD' TopLevelConstraint\n" + "AddColumn <- 'ADD' 'COLUMN'? IfNotExists? AddColumnEntry\n" + "AddColumnEntry <- DottedIdentifier Type? GeneratedColumn? ColumnConstraint*\n" + "DropColumn <- 'DROP' 'COLUMN'? IfExists? NestedColumnName DropBehavior?\n" + "AlterColumn <- 'ALTER' 'COLUMN'? NestedColumnName AlterColumnEntry\n" + "RenameColumn <- 'RENAME' 'COLUMN'? NestedColumnName 'TO' Identifier\n" + "NestedColumnName <- IdentifierDot* ColumnName\n" + "IdentifierDot <- Identifier '.'\n" + "RenameAlter <- 'RENAME' 'TO' Identifier\n" + "SetPartitionedBy <- 'SET' 'PARTITIONED' 'BY' Parens(List(Expression))\n" + "ResetPartitionedBy <- 'RESET' 'PARTITIONED' 'BY'\n" + "SetSortedBy <- 'SET' 'SORTED' 'BY' Parens(OrderByExpressions)\n" + "ResetSortedBy <- 'RESET' 'SORTED' 'BY'\n" + "SetOptions <- 'SET' RelOptionList\n" + "ResetOptions <- 'RESET' RelOptionList\n" + "AlterColumnEntry <- AddOrDropDefault / ChangeNullability / AlterType\n" + "AddOrDropDefault <- AddDefault / DropDefault\n" + "AddDefault <- 'SET' 'DEFAULT' Expression\n" + "DropDefault <- 'DROP' 'DEFAULT'\n" + "ChangeNullability <- DropOrSet 'NOT' 'NULL'\n" + "DropOrSet <- DropNullability / SetNullability\n" + "DropNullability <- 'DROP'\n" + "SetNullability <- 'SET'\n" + "AlterType <- SetData? 'TYPE' Type? UsingExpression?\n" + "SetData <- 'SET' 'DATA'?\n" + "UsingExpression <- 'USING' Expression\n" + "AlterViewStmt <- 'VIEW' IfExists? BaseTableName RenameAlter\n" + "AlterSequenceStmt <- 'SEQUENCE' IfExists? QualifiedSequenceName AlterSequenceOptions\n" + "QualifiedSequenceName <- CatalogQualification? SchemaQualification? SequenceName\n" + "AlterSequenceOptions <- RenameAlter / SetSequenceOption\n" + "SetSequenceOption <- SequenceOption+\n" + "AlterDatabaseStmt <- 'DATABASE' IfExists? Identifier 'SET' 'ALIAS' 'TO' Identifier\n" + "CreateSequenceStmt <- 'SEQUENCE' IfNotExists? QualifiedName SequenceOption*\n" + "SequenceOption <-\n" + " SeqSetCycle /\n" + " SeqSetIncrement /\n" + " SeqSetMinMax /\n" + " SeqNoMinMax /\n" + " SeqStartWith /\n" + " SeqOwnedBy\n" + "SeqSetCycle <- SeqCycle / SeqNoCycle\n" + "SeqCycle <- 'CYCLE'\n" + "SeqNoCycle <- 'NO' 'CYCLE'\n" + "SeqSetIncrement <- 'INCREMENT' 'BY'? Expression\n" + "SeqSetMinMax <- SeqMinOrMax Expression\n" + "SeqNoMinMax <- 'NO' SeqMinOrMax\n" + "SeqStartWith <- 'START' 'WITH'? Expression\n" + "SeqOwnedBy <- 'OWNED' 'BY' QualifiedName\n" + "SeqMinOrMax <- MinValue / MaxValue\n" + "MinValue <- 'MINVALUE'\n" + "MaxValue <- 'MAXVALUE'\n" + "ExplainStatement <- 'EXPLAIN' ExplainAnalyze? ExplainOptionList? ExplainableStatements\n" + "ExplainAnalyze <- 'ANALYZE'\n" + "ExplainOptionList <- Parens(List(ExplainOption))\n" + "ExplainOption <- ExplainOptionName Expression?\n" + "ExplainOptionName <- 'ANALYZE' / 'ANALYSE' / ColId / FuncNameKeyword / TypeNameKeyword\n" + "ExplainSelectStatement <- SelectStatementInternal\n" + "ExplainableStatements <-\n" + " AlterStatement /\n" + " AnalyzeStatement /\n" + " CallStatement /\n" + " CheckpointStatement /\n" + " CopyStatement /\n" + " CreateStatement /\n" + " DeallocateStatement /\n" + " DeleteStatement /\n" + " DropStatement /\n" + " ExecuteStatement /\n" + " InsertStatement /\n" + " LoadStatement /\n" + " MergeIntoStatement /\n" + " PragmaStatement /\n" + " PrepareStatement /\n" + " ExplainSelectStatement /\n" + " TransactionStatement /\n" + " UpdateStatement /\n" + " VacuumStatement /\n" + " SetStatement /\n" + " ResetStatement\n" + "AnalyzeStatement <- 'ANALYZE' AnalyzeVerbose? AnalyzeTarget?\n" + "AnalyzeTarget <- BaseTableName NameList?\n" + "AnalyzeVerbose <- 'VERBOSE'\n" + "CreateMacroStmt <- MacroOrFunction IfNotExists? QualifiedName List(MacroDefinition)\n" + "MacroOrFunction <- MacroKeyword / FunctionKeyword\n" + "MacroKeyword <- 'MACRO'\n" + "FunctionKeyword <- 'FUNCTION'\n" + "MacroDefinition <- Parens(MacroParameters?) 'AS' MacroDefinitionBody\n" + "MacroDefinitionBody <- TableMacroDefinition / ScalarMacroDefinition\n" + "MacroParameters <- List(MacroParameter)\n" + "MacroParameter <- NamedParameter / SimpleParameter\n" + "SimpleParameter <- TypeFuncName Type?\n" + "ScalarMacroDefinition <- Expression\n" + "TableMacroDefinition <- 'TABLE' SelectStatementInternal\n" + "CommentStatement <- 'COMMENT' 'ON' CommentOnType DottedIdentifier 'IS' CommentValue\n" + "CommentOnType <- CommentTable / CommentSequence / CommentFunction / CommentMacroTable / CommentMacro /\n" + " CommentView / CommentDatabase / CommentIndex / CommentSchema / CommentType / CommentColumn\n" + "CommentTable <- 'TABLE'\n" + "CommentSequence <- 'SEQUENCE'\n" + "CommentFunction <- 'FUNCTION'\n" + "CommentMacroTable <- 'MACRO' 'TABLE'\n" + "CommentMacro <- 'MACRO'\n" + "CommentView <- 'VIEW'\n" + "CommentDatabase <- 'DATABASE'\n" + "CommentIndex <- 'INDEX'\n" + "CommentSchema <- 'SCHEMA'\n" + "CommentType <- 'TYPE'\n" + "CommentColumn <- 'COLUMN'\n" + "CommentValue <- NullLiteral / StringLiteral\n" + "CreateTriggerStmt <- 'TRIGGER' IfNotExists? TriggerName TriggerTiming TriggerEvent 'ON' BaseTableName ReferencingClause? ForEachClause? TriggerBody\n" + "TriggerBody <- InsertStatement / UpdateStatement / DeleteStatement / MergeIntoStatement\n" + "TriggerName <- Identifier\n" + "ReferencingClause <- 'REFERENCING' ReferencingItem ReferencingItem?\n" + "ReferencingItem <- ReferencingNewTableAs / ReferencingOldTableAs\n" + "ReferencingNewTableAs <- 'NEW' 'TABLE' 'AS' ColId\n" + "ReferencingOldTableAs <- 'OLD' 'TABLE' 'AS' ColId\n" + "TriggerTiming <- TriggerBefore / TriggerAfter / TriggerInsteadOf\n" + "TriggerBefore <- 'BEFORE'\n" + "TriggerAfter <- 'AFTER'\n" + "TriggerInsteadOf <- 'INSTEAD' 'OF'\n" + "TriggerEvent <- TriggerEventUpdateOf / TriggerEventInsert / TriggerEventDelete / TriggerEventUpdate\n" + "TriggerEventInsert <- 'INSERT'\n" + "TriggerEventDelete <- 'DELETE'\n" + "TriggerEventUpdate <- 'UPDATE'\n" + "TriggerEventUpdateOf <- 'UPDATE' 'OF' TriggerColumnList\n" + "TriggerColumnList <- List(ColId)\n" + "ForEachClause <- ForEachRow / ForEachStatement\n" + "ForEachRow <- 'FOR' 'EACH' 'ROW'\n" + "ForEachStatement <- 'FOR' 'EACH' 'STATEMENT'\n" + "AttachStatement <- 'ATTACH' OrReplace? IfNotExists? Database? DatabasePath AttachAlias? AttachOptions?\n" + "Database <- 'DATABASE'\n" + "DatabasePath <- Expression\n" + "AttachAlias <- 'AS' ColId\n" + "AttachOptions <- GenericCopyOptionList\n" + "DetachStatement <- 'DETACH' Database? IfExists? CatalogName\n" + "UseStatement <- 'USE' UseTarget\n" + "UseTarget <- UseTargetCatalogSchema / SchemaNameAsUseTarget / CatalogNameAsUseTarget\n" + "SchemaNameAsUseTarget <- SchemaName\n" + "CatalogNameAsUseTarget <- CatalogName\n" + "UseTargetCatalogSchema <- CatalogName '.' ReservedSchemaName DotIdentifier*\n" + "DotIdentifier <- '.' Identifier\n" + "CallStatement <- 'CALL' QualifiedTableFunction TableFunctionArguments\n" }; diff --git a/src/duckdb/src/include/duckdb/planner/binder.hpp b/src/duckdb/src/include/duckdb/planner/binder.hpp index 725254973..d3f704541 100644 --- a/src/duckdb/src/include/duckdb/planner/binder.hpp +++ b/src/duckdb/src/include/duckdb/planner/binder.hpp @@ -465,9 +465,9 @@ class Binder : public enable_shared_from_this { BoundStatement BindNode(QueryNode &node); BoundStatement BindNode(StatementNode &node); BoundStatement BindNode(InsertQueryNode &node); - unique_ptr TryExpandTriggers(QueryNode &node, vector> &returning_list, - TableCatalogEntry &table, TriggerEventType event_type); - BoundStatement ExpandTriggers(QueryNode &node, vector> &returning_list, + unique_ptr TryExpandTriggers(QueryNode &node, TableCatalogEntry &table, + TriggerEventType event_type); + BoundStatement ExpandTriggers(QueryNode &node, TableCatalogEntry &table, const vector> &before_triggers, const vector> &after_triggers); BoundStatement BindNode(UpdateQueryNode &node); diff --git a/src/duckdb/src/parser/peg/transformer/transform_create_trigger.cpp b/src/duckdb/src/parser/peg/transformer/transform_create_trigger.cpp index 565ab846f..39a1e58d8 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_create_trigger.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_create_trigger.cpp @@ -3,9 +3,11 @@ #include "duckdb/parser/statement/insert_statement.hpp" #include "duckdb/parser/statement/update_statement.hpp" #include "duckdb/parser/statement/delete_statement.hpp" +#include "duckdb/parser/statement/merge_into_statement.hpp" #include "duckdb/parser/query_node/insert_query_node.hpp" #include "duckdb/parser/query_node/update_query_node.hpp" #include "duckdb/parser/query_node/delete_query_node.hpp" +#include "duckdb/parser/query_node/merge_query_node.hpp" namespace duckdb { @@ -17,6 +19,8 @@ static unique_ptr ExtractQueryNode(unique_ptr stmt) { return unique_ptr_cast(std::move(stmt->Cast().node)); case StatementType::DELETE_STATEMENT: return unique_ptr_cast(std::move(stmt->Cast().node)); + case StatementType::MERGE_INTO_STATEMENT: + return unique_ptr_cast(std::move(stmt->Cast().node)); default: throw ParserException("Trigger body must be an INSERT, UPDATE, or DELETE statement"); } diff --git a/src/duckdb/src/planner/binder.cpp b/src/duckdb/src/planner/binder.cpp index 24fdc8d75..fa1107c45 100644 --- a/src/duckdb/src/planner/binder.cpp +++ b/src/duckdb/src/planner/binder.cpp @@ -594,154 +594,4 @@ shared_ptr Binder::CreateBinderWithSearchPath(const Identifier &catalog_ return new_binder; } -unique_ptr Binder::TryExpandTriggers(QueryNode &node, - vector> &returning_list, - TableCatalogEntry &table, TriggerEventType event_type) { - auto &expanded_tables = global_binder_state->trigger_expanded_tables; - if (expanded_tables.find(table) != expanded_tables.end()) { - if (global_binder_state->trigger_creation_table == &table) { - throw NotImplementedException("Recursive trigger chains are not yet supported (trigger cycle detected " - "through trigger \"%s\" on table \"%s\")", - global_binder_state->trigger_creation_name, table.name); - } - return nullptr; - } - auto txn = table.ParentCatalog().GetCatalogTransaction(context); - auto before_triggers = table.GetTriggersForEvent(txn, TriggerTiming::BEFORE, event_type); - auto after_triggers = table.GetTriggersForEvent(txn, TriggerTiming::AFTER, event_type); - - // UPDATE OF : drop triggers whose OF list is disjoint from the SET list. - // Triggers without an OF list are unrestricted and always fire. - if (event_type == TriggerEventType::UPDATE_EVENT && node.type == QueryNodeType::UPDATE_QUERY_NODE) { - auto &update_node = node.Cast(); - identifier_set_t updated_columns; - if (update_node.set_info) { - updated_columns.insert(update_node.set_info->columns.begin(), update_node.set_info->columns.end()); - } - auto trigger_does_not_fire = [&](const_reference trig) { - const auto &of_cols = trig.get().columns; - return !of_cols.empty() && std::none_of(of_cols.begin(), of_cols.end(), - [&](const Identifier &c) { return updated_columns.count(c) > 0; }); - }; - auto drop_non_firing = [&](vector> &triggers) { - triggers.erase(std::remove_if(triggers.begin(), triggers.end(), trigger_does_not_fire), triggers.end()); - }; - drop_non_firing(before_triggers); - drop_non_firing(after_triggers); - } - - if (before_triggers.empty() && after_triggers.empty()) { - return nullptr; - } - if (!returning_list.empty()) { - throw NotImplementedException("RETURNING is not yet supported on tables with triggers"); - } - if (node.type == QueryNodeType::INSERT_QUERY_NODE) { - auto &insert_node = node.Cast(); - if (insert_node.on_conflict_info && insert_node.on_conflict_info->action_type != OnConflictAction::NOTHING) { - // Only AFTER triggers can carry REFERENCING NEW TABLE — BEFORE rejects it at CREATE time. - for (auto &trigger : after_triggers) { - if (!trigger.get().referencing_new_table.empty()) { - throw NotImplementedException( - "ON CONFLICT DO UPDATE is not yet supported with REFERENCING NEW TABLE AS triggers"); - } - } - } - } - expanded_tables.insert(table); - auto bound = ExpandTriggers(node, returning_list, before_triggers, after_triggers); - - // Erasing from the set, so we will track expanded tables only while we're on the same node in the recursive stack, - // meaning we're on the same "trigger" in the trigger chain. - expanded_tables.erase(table); - return make_uniq(std::move(bound)); -} - -static constexpr const char *TRIGGER_BASE_CTE_PREFIX = "__duckdb_trigger_base_"; -static constexpr const char *TRIGGER_BODY_CTE_PREFIX = "__duckdb_trigger_body_"; -static constexpr const char *TRIGGER_BEFORE_BODY_CTE_PREFIX = "__duckdb_trigger_before_body_"; - -static unique_ptr MakeTransitionTableAliasCTE(const Identifier &base_cte_name) { - auto alias_cte = make_uniq(); - auto alias_select = make_uniq(); - alias_select->select_list.push_back(make_uniq()); - auto alias_ref = make_uniq(); - alias_ref->table_name = base_cte_name; - alias_select->from_table = std::move(alias_ref); - alias_cte->query_node = std::move(alias_select); - alias_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; - return alias_cte; -} - -BoundStatement Binder::ExpandTriggers(QueryNode &node, vector> &returning_list, - const vector> &before_triggers, - const vector> &after_triggers) { - D_ASSERT(!before_triggers.empty() || !after_triggers.empty()); - - D_ASSERT(returning_list.empty()); - returning_list.push_back(make_uniq()); - - auto uuid_suffix = UUID::ToString(UUID::GenerateRandomUUID()); - Identifier base_cte_name(TRIGGER_BASE_CTE_PREFIX + uuid_suffix); - - // count(*) over the base CTE gives CHANGED_ROWS ("N rows affected") to the client - auto outer = make_uniq(); - outer->select_list.push_back(make_uniq("count_star", vector>())); - auto from_ref = make_uniq(); - from_ref->table_name = base_cte_name; - outer->from_table = std::move(from_ref); - - // CTE definition order == execution order: BEFORE bodies, then base (DML), then AFTER bodies. - - // BEFORE bodies (no transition tables — REFERENCING is rejected at CREATE TRIGGER time) - for (idx_t i = 0; i < before_triggers.size(); i++) { - auto &trigger = before_triggers[i].get(); - auto body_cte_name = string(TRIGGER_BEFORE_BODY_CTE_PREFIX) + to_string(i + 1) + "_" + uuid_suffix; - - auto trig_cte = make_uniq(); - trig_cte->query_node = trigger.trigger_action->Copy(); - trig_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; - trig_cte->is_trigger_generated = true; - - outer->cte_map.map[Identifier(body_cte_name)] = std::move(trig_cte); - } - - // Base CTE: the original DML, materialized so AFTER bodies can scan it (transition tables) - auto base_cte = make_uniq(); - base_cte->query_node = node.Copy(); - base_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_ALWAYS; - base_cte->is_trigger_generated = true; - outer->cte_map.map[base_cte_name] = std::move(base_cte); - - // AFTER bodies — may reference base via REFERENCING NEW/OLD TABLE aliases - for (idx_t i = 0; i < after_triggers.size(); i++) { - auto &trigger = after_triggers[i].get(); - auto body_cte_name = string(TRIGGER_BODY_CTE_PREFIX) + to_string(i + 1) + "_" + uuid_suffix; - - auto trig_cte = make_uniq(); - trig_cte->query_node = trigger.trigger_action->Copy(); - trig_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; - trig_cte->is_trigger_generated = true; - - // Inject the transition-table aliases (REFERENCING NEW/OLD TABLE) into this trigger body's own - // cte_map. That scopes the aliases to this trigger only (sibling triggers can't see them), and - // if the body has a local WITH that defines the same name, the local WITH shadows the alias. - auto &body_map = trig_cte->query_node->cte_map.map; - if (!trigger.referencing_new_table.empty() && body_map.find(trigger.referencing_new_table) == body_map.end()) { - body_map[trigger.referencing_new_table] = MakeTransitionTableAliasCTE(base_cte_name); - } - if (!trigger.referencing_old_table.empty() && body_map.find(trigger.referencing_old_table) == body_map.end()) { - body_map[trigger.referencing_old_table] = MakeTransitionTableAliasCTE(base_cte_name); - } - - outer->cte_map.map[Identifier(body_cte_name)] = std::move(trig_cte); - } - - auto bound = Bind(*outer); - auto &properties = GetStatementProperties(); - properties.return_type = StatementReturnType::CHANGED_ROWS; - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; - return bound; -} - } // namespace duckdb diff --git a/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp b/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp new file mode 100644 index 000000000..14288adb1 --- /dev/null +++ b/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp @@ -0,0 +1,395 @@ +#include "duckdb/planner/binder.hpp" + +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/catalog/catalog_entry/trigger_catalog_entry.hpp" +#include "duckdb/common/enums/cte_materialize.hpp" +#include "duckdb/common/enums/trigger_type.hpp" +#include "duckdb/common/types/uuid.hpp" +#include "duckdb/parser/common_table_expression_info.hpp" +#include "duckdb/parser/expression/columnref_expression.hpp" +#include "duckdb/parser/expression/function_expression.hpp" +#include "duckdb/parser/expression/star_expression.hpp" +#include "duckdb/parser/parsed_expression_iterator.hpp" +#include "duckdb/parser/qualified_name.hpp" +#include "duckdb/parser/query_node/delete_query_node.hpp" +#include "duckdb/parser/query_node/insert_query_node.hpp" +#include "duckdb/parser/query_node/select_node.hpp" +#include "duckdb/parser/query_node/update_query_node.hpp" +#include "duckdb/parser/statement/insert_statement.hpp" +#include "duckdb/parser/tableref/basetableref.hpp" +#include "duckdb/common/column_index.hpp" +#include "duckdb/common/identifier.hpp" +#include "duckdb/planner/expression/bound_columnref_expression.hpp" +#include "duckdb/planner/expression_iterator.hpp" +#include "duckdb/planner/expression_binder/returning_binder.hpp" +#include "duckdb/planner/operator/logical_projection.hpp" + +#include +#include + +namespace duckdb { + +// Defined in binder.cpp — rejects 'excluded'-qualified columns in RETURNING, matching the no-trigger path. +void VerifyNotExcluded(const ParsedExpression &root_expr); + +unique_ptr Binder::TryExpandTriggers(QueryNode &node, TableCatalogEntry &table, + TriggerEventType event_type) { + D_ASSERT(node.type == QueryNodeType::INSERT_QUERY_NODE || node.type == QueryNodeType::UPDATE_QUERY_NODE || + node.type == QueryNodeType::DELETE_QUERY_NODE); + auto &expanded_tables = global_binder_state->trigger_expanded_tables; + if (expanded_tables.find(table) != expanded_tables.end()) { + if (global_binder_state->trigger_creation_table == &table) { + throw NotImplementedException("Recursive trigger chains are not yet supported (trigger cycle detected " + "through trigger \"%s\" on table \"%s\")", + global_binder_state->trigger_creation_name, table.name); + } + return nullptr; + } + auto txn = table.ParentCatalog().GetCatalogTransaction(context); + auto before_triggers = table.GetTriggersForEvent(txn, TriggerTiming::BEFORE, event_type); + auto after_triggers = table.GetTriggersForEvent(txn, TriggerTiming::AFTER, event_type); + + // UPDATE OF : drop triggers whose OF list is disjoint from the SET list. + // Triggers without an OF list are unrestricted and always fire. + if (event_type == TriggerEventType::UPDATE_EVENT && node.type == QueryNodeType::UPDATE_QUERY_NODE) { + auto &update_node = node.Cast(); + identifier_set_t updated_columns; + if (update_node.set_info) { + updated_columns.insert(update_node.set_info->columns.begin(), update_node.set_info->columns.end()); + } + auto trigger_does_not_fire = [&](const_reference trig) { + const auto &of_cols = trig.get().columns; + return !of_cols.empty() && std::none_of(of_cols.begin(), of_cols.end(), + [&](const Identifier &c) { return updated_columns.count(c) > 0; }); + }; + auto drop_non_firing = [&](vector> &triggers) { + triggers.erase(std::remove_if(triggers.begin(), triggers.end(), trigger_does_not_fire), triggers.end()); + }; + drop_non_firing(before_triggers); + drop_non_firing(after_triggers); + } + + if (before_triggers.empty() && after_triggers.empty()) { + return nullptr; + } + if (node.type == QueryNodeType::INSERT_QUERY_NODE) { + auto &insert_node = node.Cast(); + if (insert_node.on_conflict_info && insert_node.on_conflict_info->action_type != OnConflictAction::NOTHING) { + // Only AFTER triggers can carry REFERENCING NEW TABLE — BEFORE rejects it at CREATE time. + for (auto &trigger : after_triggers) { + if (!trigger.get().referencing_new_table.empty()) { + throw NotImplementedException( + "ON CONFLICT DO UPDATE is not yet supported with REFERENCING NEW TABLE AS triggers"); + } + } + } + } + expanded_tables.insert(table); + auto bound = ExpandTriggers(node, table, before_triggers, after_triggers); + + // Only track this table as expanded for the duration of its own subtree in the trigger chain. + expanded_tables.erase(table); + return make_uniq(std::move(bound)); +} + +static constexpr const char *TRIGGER_BASE_CTE_PREFIX = "__duckdb_trigger_base_"; +static constexpr const char *TRIGGER_BODY_CTE_PREFIX = "__duckdb_trigger_body_"; +static constexpr const char *TRIGGER_BEFORE_BODY_CTE_PREFIX = "__duckdb_trigger_before_body_"; + +static unique_ptr MakeTransitionTableAliasCTE(const Identifier &base_cte_name, + const identifier_set_t &exclude_columns) { + auto alias_cte = make_uniq(); + auto alias_select = make_uniq(); + auto star = make_uniq(); + // Hide injected virtual columns from trigger bodies that SELECT * over the transition table. + for (auto &name : exclude_columns) { + star->ExcludeListMutable().insert(QualifiedColumnName(name)); + } + alias_select->select_list.push_back(std::move(star)); + auto alias_ref = make_uniq(); + alias_ref->table_name = base_cte_name; + alias_select->from_table = std::move(alias_ref); + alias_cte->query_node = std::move(alias_select); + alias_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; + return alias_cte; +} + +static vector> &GetDMLReturningList(QueryNode &node) { + switch (node.type) { + case QueryNodeType::INSERT_QUERY_NODE: + return node.Cast().returning_list; + case QueryNodeType::UPDATE_QUERY_NODE: + return node.Cast().returning_list; + case QueryNodeType::DELETE_QUERY_NODE: + return node.Cast().returning_list; + default: + throw InternalException("GetDMLReturningList: unexpected node type"); + } +} + +static Identifier GetTableAlias(const QueryNode &node, const Identifier &fallback) { + switch (node.type) { + case QueryNodeType::INSERT_QUERY_NODE: { + auto &n = node.Cast(); + if (n.table_ref && !n.table_ref->alias.empty()) { + return n.table_ref->alias; + } + return fallback; + } + case QueryNodeType::UPDATE_QUERY_NODE: { + auto &n = node.Cast(); + if (n.table && !n.table->alias.empty()) { + return n.table->alias; + } + return fallback; + } + case QueryNodeType::DELETE_QUERY_NODE: { + auto &n = node.Cast(); + if (n.table && !n.table->alias.empty()) { + return n.table->alias; + } + return fallback; + } + default: + D_ASSERT(false); + return fallback; + } +} + +// Raw table_ref alias (empty if none) — an empty alias lets the binding derive +// catalog.schema.table from the entry, so qualified RETURNING columns resolve. +static Identifier GetReturningAlias(const QueryNode &node) { + switch (node.type) { + case QueryNodeType::INSERT_QUERY_NODE: + return node.Cast().table_ref ? node.Cast().table_ref->alias : Identifier(); + case QueryNodeType::UPDATE_QUERY_NODE: + return node.Cast().table ? node.Cast().table->alias : Identifier(); + case QueryNodeType::DELETE_QUERY_NODE: + return node.Cast().table ? node.Cast().table->alias : Identifier(); + default: + return Identifier(); + } +} + +// Virtual columns exposed to RETURNING — only DELETE, mirroring the no-trigger path. +static virtual_column_map_t ReturningVirtualColumns(const QueryNode &node, const TableCatalogEntry &table) { + if (node.type == QueryNodeType::DELETE_QUERY_NODE) { + return table.GetVirtualColumns(); + } + return virtual_column_map_t(); +} + +// Virtual columns the RETURNING list references, so the base CTE can materialise them (RETURNING * +// does not include rowid). Matched on the trailing identifier — the only table in scope is the +// target. Returns (id, name) pairs, deduplicated. +static vector> ReferencedVirtualColumns(vector> &returning_list, + const virtual_column_map_t &virtual_cols, + const TableCatalogEntry &table) { + vector> result; + if (virtual_cols.empty()) { + return result; + } + // A virtual column shadowed by a real column of the same name is not virtual here: RETURNING * + // already materialises the real column, and injecting would duplicate the name. + identifier_set_t real_names; + for (auto &col : table.GetColumns().Logical()) { + real_names.insert(col.Name()); + } + unordered_set seen; + for (auto &expr : returning_list) { + ParsedExpressionIterator::VisitExpression(*expr, [&](const ColumnRefExpression &cr) { + auto &cn = cr.ColumnNames(); + if (cn.empty()) { + return; + } + for (auto &vc : virtual_cols) { + if (real_names.find(vc.second.name) != real_names.end()) { + continue; + } + if (cn.back() == vc.second.name && seen.insert(vc.first).second) { + result.emplace_back(vc.first, vc.second.name); + } + } + }); + } + return result; +} + +static void AddAfterTriggerCTEs(SelectNode &outer, const vector> &after_triggers, + const Identifier &base_cte_name, const string &uuid_suffix, + const identifier_set_t &injected_names) { + for (idx_t i = 0; i < after_triggers.size(); i++) { + auto &trigger = after_triggers[i].get(); + Identifier body_cte_name(string(TRIGGER_BODY_CTE_PREFIX) + to_string(i + 1) + "_" + uuid_suffix); + + auto trig_cte = make_uniq(); + trig_cte->query_node = trigger.trigger_action->Copy(); + trig_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; + trig_cte->is_trigger_generated = true; + + // Scoped to this body so sibling triggers can't see the alias. + auto &body_map = trig_cte->query_node->cte_map.map; + if (!trigger.referencing_new_table.empty() && body_map.find(trigger.referencing_new_table) == body_map.end()) { + body_map[trigger.referencing_new_table] = MakeTransitionTableAliasCTE(base_cte_name, injected_names); + } + if (!trigger.referencing_old_table.empty() && body_map.find(trigger.referencing_old_table) == body_map.end()) { + body_map[trigger.referencing_old_table] = MakeTransitionTableAliasCTE(base_cte_name, injected_names); + } + + outer.cte_map.map[body_cte_name] = std::move(trig_cte); + } +} + +// Build the trigger CTE chain as a SelectNode: BEFORE bodies → base DML → AFTER bodies. +// For RETURNING the outer projection is a plain SELECT *, rebound through ReturningBinder later. +static unique_ptr BuildTriggerChain(const QueryNode &node, const TableCatalogEntry &table, + const vector> &before_triggers, + const vector> &after_triggers, + const string &uuid_suffix, const Identifier &base_cte_name, + bool has_returning, + const vector> &injected_virtuals) { + auto outer = make_uniq(); + if (has_returning) { + outer->select_list.push_back(make_uniq()); + } else { + outer->select_list.push_back( + make_uniq("count_star", vector>())); + } + auto from_ref = make_uniq(); + from_ref->table_name = base_cte_name; + from_ref->alias = GetTableAlias(node, table.name); + outer->from_table = std::move(from_ref); + + // BEFORE bodies (no transition tables — REFERENCING is rejected at CREATE time). + for (idx_t i = 0; i < before_triggers.size(); i++) { + Identifier body_cte_name(string(TRIGGER_BEFORE_BODY_CTE_PREFIX) + to_string(i + 1) + "_" + uuid_suffix); + auto trig_cte = make_uniq(); + trig_cte->query_node = before_triggers[i].get().trigger_action->Copy(); + trig_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_DEFAULT; + trig_cte->is_trigger_generated = true; + outer->cte_map.map[body_cte_name] = std::move(trig_cte); + } + + // Base CTE: the DML with RETURNING * (full rows for transition tables), plus referenced + // virtual columns appended so they are materialised for the RETURNING projection. + auto base_node = node.Copy(); + auto &base_returning = GetDMLReturningList(*base_node); + base_returning.push_back(make_uniq()); + identifier_set_t injected_names; + for (auto &vc : injected_virtuals) { + base_returning.push_back(make_uniq(vc.second)); + injected_names.insert(vc.second); + } + auto base_cte = make_uniq(); + base_cte->query_node = std::move(base_node); + base_cte->materialized = CTEMaterialize::CTE_MATERIALIZE_ALWAYS; + base_cte->is_trigger_generated = true; + outer->cte_map.map[base_cte_name] = std::move(base_cte); + + AddAfterTriggerCTEs(*outer, after_triggers, base_cte_name, uuid_suffix, injected_names); + return outer; +} + +BoundStatement Binder::ExpandTriggers(QueryNode &node, TableCatalogEntry &table, + const vector> &before_triggers, + const vector> &after_triggers) { + D_ASSERT(!before_triggers.empty() || !after_triggers.empty()); + D_ASSERT(node.type == QueryNodeType::INSERT_QUERY_NODE || node.type == QueryNodeType::UPDATE_QUERY_NODE || + node.type == QueryNodeType::DELETE_QUERY_NODE); + + // Drain before copying so the base CTE copy's returning_list starts empty. + auto user_returning_list = std::move(GetDMLReturningList(node)); + bool has_returning = !user_returning_list.empty(); + + auto virtual_columns = ReturningVirtualColumns(node, table); + auto injected_virtuals = has_returning ? ReferencedVirtualColumns(user_returning_list, virtual_columns, table) + : vector>(); + + auto uuid_suffix = UUID::ToString(UUID::GenerateRandomUUID()); + Identifier base_cte_name(TRIGGER_BASE_CTE_PREFIX + uuid_suffix); + + auto outer = BuildTriggerChain(node, table, before_triggers, after_triggers, uuid_suffix, base_cte_name, + has_returning, injected_virtuals); + auto chain = Bind(*outer); + + if (!has_returning) { + auto &properties = GetStatementProperties(); + properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.return_type = StatementReturnType::CHANGED_ROWS; + return chain; + } + + // SELECT * over the base CTE yields a projection with contiguous bindings (index, 0..n-1), so we + // bind the RETURNING list against that index directly as an identity base-table binding. + auto child_bindings = chain.plan->GetColumnBindings(); + D_ASSERT(!child_bindings.empty() && child_bindings.size() == chain.types.size()); + auto base_index = child_bindings[0].table_index; + + // Bind RETURNING with ReturningBinder over a base-table binding of the real table — same rules as + // the no-trigger path (rejects aggregates/subqueries/windows, resolves qualified columns, virtual + // vs real rowid). bound_columns is the identity over all logical columns (generated included) + // because our RETURNING * child materialises every logical column in order. + auto returning_binder_owner = Binder::CreateBinder(context); + vector col_names; + vector col_types; + vector bound_columns; + idx_t logical_count = 0; + for (auto &col : table.GetColumns().Logical()) { + col_names.push_back(col.Name()); + col_types.push_back(col.Type()); + bound_columns.emplace_back(logical_count); + logical_count++; + } + returning_binder_owner->bind_context.AddBaseTable(base_index, GetReturningAlias(node), col_names, col_types, + bound_columns, table, std::move(virtual_columns)); + ReturningBinder returning_binder(*returning_binder_owner, context); + + vector> expanded_returning; + returning_binder_owner->ExpandStarExpressions(user_returning_list, expanded_returning); + if (expanded_returning.empty()) { + throw BinderException("RETURNING list is empty!"); + } + BoundStatement result; + vector> proj_exprs; + for (auto &returning_expr : expanded_returning) { + VerifyNotExcluded(*returning_expr); + LogicalType result_type; + auto bound_expr = returning_binder.Bind(returning_expr, &result_type); + result.names.push_back(bound_expr->GetName()); + result.types.push_back(result_type); + proj_exprs.push_back(std::move(bound_expr)); + } + + // Virtual columns bind to a sentinel id, but the chain materialised them as trailing columns at + // logical_count + k. Remap those bindings to their real positions. + if (!injected_virtuals.empty()) { + unordered_map remap; + for (idx_t k = 0; k < injected_virtuals.size(); k++) { + remap[injected_virtuals[k].first] = logical_count + k; + } + for (auto &expr : proj_exprs) { + ExpressionIterator::VisitExpressionMutable( + expr, [&](BoundColumnRefExpression &colref, unique_ptr &) { + auto &binding = colref.BindingMutable(); + if (binding.table_index != base_index) { + return; + } + auto it = remap.find(binding.column_index.GetIndexUnsafe()); + if (it != remap.end()) { + binding.column_index = ProjectionIndex(it->second); + } + }); + } + } + + auto returning_projection = make_uniq(GenerateTableIndex(), std::move(proj_exprs)); + returning_projection->AddChild(std::move(chain.plan)); + result.plan = std::move(returning_projection); + + auto &properties = GetStatementProperties(); + properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.return_type = StatementReturnType::QUERY_RESULT; + return result; +} + +} // namespace duckdb diff --git a/src/duckdb/src/planner/binder/statement/bind_delete.cpp b/src/duckdb/src/planner/binder/statement/bind_delete.cpp index d549962fe..3f2a30b20 100644 --- a/src/duckdb/src/planner/binder/statement/bind_delete.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_delete.cpp @@ -30,7 +30,7 @@ BoundStatement Binder::BindNode(DeleteQueryNode &node) { } auto &table = *table_ptr; - if (auto expanded = TryExpandTriggers(node, node.returning_list, table, TriggerEventType::DELETE_EVENT)) { + if (auto expanded = TryExpandTriggers(node, table, TriggerEventType::DELETE_EVENT)) { return std::move(*expanded); } diff --git a/src/duckdb/src/planner/binder/statement/bind_insert.cpp b/src/duckdb/src/planner/binder/statement/bind_insert.cpp index 3f42d5b5b..6d1ce15ce 100644 --- a/src/duckdb/src/planner/binder/statement/bind_insert.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_insert.cpp @@ -543,7 +543,7 @@ BoundStatement Binder::BindNode(InsertQueryNode &node) { BindSchemaOrCatalog(node.catalog, node.schema); auto &table = Catalog::GetEntry(context, node.catalog, node.schema, node.table); - if (auto expanded = TryExpandTriggers(node, node.returning_list, table, TriggerEventType::INSERT_EVENT)) { + if (auto expanded = TryExpandTriggers(node, table, TriggerEventType::INSERT_EVENT)) { return std::move(*expanded); } diff --git a/src/duckdb/src/planner/binder/statement/bind_update.cpp b/src/duckdb/src/planner/binder/statement/bind_update.cpp index 093559068..7f0e7c0be 100644 --- a/src/duckdb/src/planner/binder/statement/bind_update.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_update.cpp @@ -140,7 +140,7 @@ BoundStatement Binder::BindNode(UpdateQueryNode &node) { } auto &table = *table_ptr; - if (auto expanded = TryExpandTriggers(node, node.returning_list, table, TriggerEventType::UPDATE_EVENT)) { + if (auto expanded = TryExpandTriggers(node, table, TriggerEventType::UPDATE_EVENT)) { return std::move(*expanded); } diff --git a/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp b/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp index 1fdfd5cdb..8cf8af345 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp @@ -1,8 +1,8 @@ #include "extension/core_functions/aggregate/algebraic/avg.cpp" +#include "extension/core_functions/aggregate/algebraic/corr.cpp" + #include "extension/core_functions/aggregate/algebraic/covar.cpp" #include "extension/core_functions/aggregate/algebraic/stddev.cpp" -#include "extension/core_functions/aggregate/algebraic/corr.cpp" - diff --git a/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp b/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp index ffd7c8dad..dfecded9e 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp @@ -1,20 +1,20 @@ +#include "extension/core_functions/aggregate/distributive/bitagg.cpp" + #include "extension/core_functions/aggregate/distributive/approx_count.cpp" +#include "extension/core_functions/aggregate/distributive/bool.cpp" + #include "extension/core_functions/aggregate/distributive/arg_min_max.cpp" -#include "extension/core_functions/aggregate/distributive/product.cpp" +#include "extension/core_functions/aggregate/distributive/string_agg.cpp" -#include "extension/core_functions/aggregate/distributive/skew.cpp" +#include "extension/core_functions/aggregate/distributive/sum.cpp" #include "extension/core_functions/aggregate/distributive/kurtosis.cpp" -#include "extension/core_functions/aggregate/distributive/sum.cpp" - -#include "extension/core_functions/aggregate/distributive/bitagg.cpp" +#include "extension/core_functions/aggregate/distributive/skew.cpp" #include "extension/core_functions/aggregate/distributive/bitstring_agg.cpp" -#include "extension/core_functions/aggregate/distributive/string_agg.cpp" - -#include "extension/core_functions/aggregate/distributive/bool.cpp" +#include "extension/core_functions/aggregate/distributive/product.cpp" diff --git a/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp b/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp index 4f892afa3..d27f74f4f 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp @@ -1,9 +1,9 @@ -#include "extension/core_functions/aggregate/holistic/quantile.cpp" - #include "extension/core_functions/aggregate/holistic/mode.cpp" #include "extension/core_functions/aggregate/holistic/reservoir_quantile.cpp" +#include "extension/core_functions/aggregate/holistic/quantile.cpp" + #include "extension/core_functions/aggregate/holistic/approx_top_k.cpp" #include "extension/core_functions/aggregate/holistic/mad.cpp" diff --git a/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp b/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp index 340382e4f..0b4f57e9c 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp @@ -1,6 +1,6 @@ -#include "extension/core_functions/aggregate/nested/histogram.cpp" - #include "extension/core_functions/aggregate/nested/list.cpp" #include "extension/core_functions/aggregate/nested/binned_histogram.cpp" +#include "extension/core_functions/aggregate/nested/histogram.cpp" + diff --git a/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp b/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp index 071bc16d4..4b5d14dc3 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp @@ -1,14 +1,14 @@ +#include "extension/core_functions/aggregate/regression/regr_sxx_syy.cpp" + +#include "extension/core_functions/aggregate/regression/regr_slope.cpp" + #include "extension/core_functions/aggregate/regression/regr_r2.cpp" #include "extension/core_functions/aggregate/regression/regr_avg.cpp" #include "extension/core_functions/aggregate/regression/regr_sxy.cpp" -#include "extension/core_functions/aggregate/regression/regr_sxx_syy.cpp" - -#include "extension/core_functions/aggregate/regression/regr_slope.cpp" +#include "extension/core_functions/aggregate/regression/regr_intercept.cpp" #include "extension/core_functions/aggregate/regression/regr_count.cpp" -#include "extension/core_functions/aggregate/regression/regr_intercept.cpp" - diff --git a/src/duckdb/ub_extension_core_functions_scalar_date.cpp b/src/duckdb/ub_extension_core_functions_scalar_date.cpp index 869059d9b..837ee7002 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_date.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_date.cpp @@ -1,20 +1,20 @@ -#include "extension/core_functions/scalar/date/time_bucket.cpp" - -#include "extension/core_functions/scalar/date/current.cpp" - -#include "extension/core_functions/scalar/date/date_sub.cpp" +#include "extension/core_functions/scalar/date/date_diff.cpp" -#include "extension/core_functions/scalar/date/make_date.cpp" +#include "extension/core_functions/scalar/date/time_bucket.cpp" -#include "extension/core_functions/scalar/date/age.cpp" +#include "extension/core_functions/scalar/date/to_interval.cpp" #include "extension/core_functions/scalar/date/date_part.cpp" -#include "extension/core_functions/scalar/date/to_interval.cpp" +#include "extension/core_functions/scalar/date/make_date.cpp" #include "extension/core_functions/scalar/date/epoch.cpp" +#include "extension/core_functions/scalar/date/date_sub.cpp" + #include "extension/core_functions/scalar/date/date_trunc.cpp" -#include "extension/core_functions/scalar/date/date_diff.cpp" +#include "extension/core_functions/scalar/date/current.cpp" + +#include "extension/core_functions/scalar/date/age.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_debug.cpp b/src/duckdb/ub_extension_core_functions_scalar_debug.cpp index 4ba1ce617..e452f015d 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_debug.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_debug.cpp @@ -1,6 +1,6 @@ -#include "extension/core_functions/scalar/debug/sleep.cpp" +#include "extension/core_functions/scalar/debug/index_key.cpp" #include "extension/core_functions/scalar/debug/vector_type.cpp" -#include "extension/core_functions/scalar/debug/index_key.cpp" +#include "extension/core_functions/scalar/debug/sleep.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_generic.cpp b/src/duckdb/ub_extension_core_functions_scalar_generic.cpp index 0242be3c2..c1a5ddd44 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_generic.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_generic.cpp @@ -1,22 +1,22 @@ -#include "extension/core_functions/scalar/generic/binning.cpp" - #include "extension/core_functions/scalar/generic/system_functions.cpp" #include "extension/core_functions/scalar/generic/stats.cpp" +#include "extension/core_functions/scalar/generic/alias.cpp" + #include "extension/core_functions/scalar/generic/current_setting.cpp" -#include "extension/core_functions/scalar/generic/least.cpp" +#include "extension/core_functions/scalar/generic/can_implicitly_cast.cpp" + +#include "extension/core_functions/scalar/generic/hash.cpp" #include "extension/core_functions/scalar/generic/type_functions.cpp" -#include "extension/core_functions/scalar/generic/replace_type.cpp" +#include "extension/core_functions/scalar/generic/binning.cpp" -#include "extension/core_functions/scalar/generic/can_implicitly_cast.cpp" +#include "extension/core_functions/scalar/generic/least.cpp" #include "extension/core_functions/scalar/generic/cast_to_type.cpp" -#include "extension/core_functions/scalar/generic/alias.cpp" - -#include "extension/core_functions/scalar/generic/hash.cpp" +#include "extension/core_functions/scalar/generic/replace_type.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_list.cpp b/src/duckdb/ub_extension_core_functions_scalar_list.cpp index a0909eac1..8db8cd259 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_list.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_list.cpp @@ -1,22 +1,22 @@ -#include "extension/core_functions/scalar/list/list_reduce.cpp" +#include "extension/core_functions/scalar/list/list_value.cpp" + +#include "extension/core_functions/scalar/list/list_transform.cpp" #include "extension/core_functions/scalar/list/flatten.cpp" #include "extension/core_functions/scalar/list/list_filter.cpp" -#include "extension/core_functions/scalar/list/list_value.cpp" - -#include "extension/core_functions/scalar/list/list_sort.cpp" - #include "extension/core_functions/scalar/list/range.cpp" -#include "extension/core_functions/scalar/list/list_transform.cpp" +#include "extension/core_functions/scalar/list/list_sort.cpp" -#include "extension/core_functions/scalar/list/list_distance.cpp" +#include "extension/core_functions/scalar/list/array_slice.cpp" #include "extension/core_functions/scalar/list/list_has_any_or_all.cpp" +#include "extension/core_functions/scalar/list/list_reduce.cpp" + #include "extension/core_functions/scalar/list/list_aggregates.cpp" -#include "extension/core_functions/scalar/list/array_slice.cpp" +#include "extension/core_functions/scalar/list/list_distance.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_map.cpp b/src/duckdb/ub_extension_core_functions_scalar_map.cpp index 78538a430..4d1a1e38d 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_map.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_map.cpp @@ -1,16 +1,16 @@ +#include "extension/core_functions/scalar/map/map_from_entries.cpp" + #include "extension/core_functions/scalar/map/switch.cpp" +#include "extension/core_functions/scalar/map/map_extract.cpp" + +#include "extension/core_functions/scalar/map/cardinality.cpp" + #include "extension/core_functions/scalar/map/map_entries.cpp" #include "extension/core_functions/scalar/map/map.cpp" #include "extension/core_functions/scalar/map/map_keys_values.cpp" -#include "extension/core_functions/scalar/map/cardinality.cpp" - #include "extension/core_functions/scalar/map/map_concat.cpp" -#include "extension/core_functions/scalar/map/map_extract.cpp" - -#include "extension/core_functions/scalar/map/map_from_entries.cpp" - diff --git a/src/duckdb/ub_extension_core_functions_scalar_string.cpp b/src/duckdb/ub_extension_core_functions_scalar_string.cpp index 9da959101..3fbf16661 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_string.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_string.cpp @@ -1,50 +1,50 @@ -#include "extension/core_functions/scalar/string/translate.cpp" - -#include "extension/core_functions/scalar/string/jaro_winkler.cpp" +#include "extension/core_functions/scalar/string/repeat.cpp" -#include "extension/core_functions/scalar/string/parse_formatted_bytes.cpp" +#include "extension/core_functions/scalar/string/parse_path.cpp" -#include "extension/core_functions/scalar/string/hamming.cpp" +#include "extension/core_functions/scalar/string/starts_with.cpp" -#include "extension/core_functions/scalar/string/unicode.cpp" +#include "extension/core_functions/scalar/string/jaro_winkler.cpp" -#include "extension/core_functions/scalar/string/chr.cpp" +#include "extension/core_functions/scalar/string/trim.cpp" #include "extension/core_functions/scalar/string/format_bytes.cpp" -#include "extension/core_functions/scalar/string/reverse.cpp" +#include "extension/core_functions/scalar/string/pad.cpp" -#include "extension/core_functions/scalar/string/hex.cpp" +#include "extension/core_functions/scalar/string/to_base.cpp" -#include "extension/core_functions/scalar/string/instr.cpp" +#include "extension/core_functions/scalar/string/bar.cpp" -#include "extension/core_functions/scalar/string/parse_path.cpp" +#include "extension/core_functions/scalar/string/translate.cpp" -#include "extension/core_functions/scalar/string/starts_with.cpp" +#include "extension/core_functions/scalar/string/url_encode.cpp" -#include "extension/core_functions/scalar/string/to_base.cpp" +#include "extension/core_functions/scalar/string/left_right.cpp" + +#include "extension/core_functions/scalar/string/reverse.cpp" #include "extension/core_functions/scalar/string/ascii.cpp" -#include "extension/core_functions/scalar/string/repeat.cpp" +#include "extension/core_functions/scalar/string/printf.cpp" -#include "extension/core_functions/scalar/string/url_encode.cpp" +#include "extension/core_functions/scalar/string/replace.cpp" -#include "extension/core_functions/scalar/string/jaccard.cpp" +#include "extension/core_functions/scalar/string/chr.cpp" -#include "extension/core_functions/scalar/string/levenshtein.cpp" +#include "extension/core_functions/scalar/string/jaccard.cpp" -#include "extension/core_functions/scalar/string/damerau_levenshtein.cpp" +#include "extension/core_functions/scalar/string/hex.cpp" -#include "extension/core_functions/scalar/string/replace.cpp" +#include "extension/core_functions/scalar/string/hamming.cpp" -#include "extension/core_functions/scalar/string/printf.cpp" +#include "extension/core_functions/scalar/string/levenshtein.cpp" -#include "extension/core_functions/scalar/string/left_right.cpp" +#include "extension/core_functions/scalar/string/instr.cpp" -#include "extension/core_functions/scalar/string/pad.cpp" +#include "extension/core_functions/scalar/string/unicode.cpp" -#include "extension/core_functions/scalar/string/trim.cpp" +#include "extension/core_functions/scalar/string/parse_formatted_bytes.cpp" -#include "extension/core_functions/scalar/string/bar.cpp" +#include "extension/core_functions/scalar/string/damerau_levenshtein.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_struct.cpp b/src/duckdb/ub_extension_core_functions_scalar_struct.cpp index 7cc473ffb..56181b4e4 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_struct.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_struct.cpp @@ -1,8 +1,8 @@ -#include "extension/core_functions/scalar/struct/struct_insert.cpp" - #include "extension/core_functions/scalar/struct/struct_values.cpp" -#include "extension/core_functions/scalar/struct/struct_update.cpp" +#include "extension/core_functions/scalar/struct/struct_insert.cpp" #include "extension/core_functions/scalar/struct/struct_keys.cpp" +#include "extension/core_functions/scalar/struct/struct_update.cpp" + diff --git a/src/duckdb/ub_extension_icu_third_party_icu_common.cpp b/src/duckdb/ub_extension_icu_third_party_icu_common.cpp index 4a230511f..d6cb3c42c 100644 --- a/src/duckdb/ub_extension_icu_third_party_icu_common.cpp +++ b/src/duckdb/ub_extension_icu_third_party_icu_common.cpp @@ -1,222 +1,222 @@ -#include "extension/icu/third_party/icu/common/uniset_props.cpp" - -#include "extension/icu/third_party/icu/common/propname.cpp" - -#include "extension/icu/third_party/icu/common/unorm.cpp" - -#include "extension/icu/third_party/icu/common/normalizer2.cpp" +#include "extension/icu/third_party/icu/common/uset_props.cpp" -#include "extension/icu/third_party/icu/common/dtintrv.cpp" +#include "extension/icu/third_party/icu/common/ustring.cpp" -#include "extension/icu/third_party/icu/common/loclikely.cpp" +#include "extension/icu/third_party/icu/common/caniter.cpp" #include "extension/icu/third_party/icu/common/cstr.cpp" -#include "extension/icu/third_party/icu/common/stringpiece.cpp" +#include "extension/icu/third_party/icu/common/ubidiln.cpp" -#include "extension/icu/third_party/icu/common/ustring.cpp" +#include "extension/icu/third_party/icu/common/utf_impl.cpp" -#include "extension/icu/third_party/icu/common/cmemory.cpp" +#include "extension/icu/third_party/icu/common/uniset_props.cpp" -#include "extension/icu/third_party/icu/common/uvectr32.cpp" +#include "extension/icu/third_party/icu/common/patternprops.cpp" -#include "extension/icu/third_party/icu/common/ucurr.cpp" +#include "extension/icu/third_party/icu/common/ushape.cpp" #include "extension/icu/third_party/icu/common/bytestream.cpp" -#include "extension/icu/third_party/icu/common/appendable.cpp" +#include "extension/icu/third_party/icu/common/characterproperties.cpp" #include "extension/icu/third_party/icu/common/locavailable.cpp" -#include "extension/icu/third_party/icu/common/utypes.cpp" +#include "extension/icu/third_party/icu/common/locid.cpp" -#include "extension/icu/third_party/icu/common/utrie_swap.cpp" +#include "extension/icu/third_party/icu/common/simpleformatter.cpp" -#include "extension/icu/third_party/icu/common/schriter.cpp" +#include "extension/icu/third_party/icu/common/uchar.cpp" -#include "extension/icu/third_party/icu/common/utext.cpp" +#include "extension/icu/third_party/icu/common/ucmndata.cpp" -#include "extension/icu/third_party/icu/common/unistr.cpp" +#include "extension/icu/third_party/icu/common/propname.cpp" -#include "extension/icu/third_party/icu/common/uloc_keytype.cpp" +#include "extension/icu/third_party/icu/common/uprops.cpp" -#include "extension/icu/third_party/icu/common/ustrtrns.cpp" +#include "extension/icu/third_party/icu/common/locresdata.cpp" -#include "extension/icu/third_party/icu/common/uniset.cpp" +#include "extension/icu/third_party/icu/common/ruleiter.cpp" #include "extension/icu/third_party/icu/common/uobject.cpp" -#include "extension/icu/third_party/icu/common/umutex.cpp" - -#include "extension/icu/third_party/icu/common/unistr_case_locale.cpp" - -#include "extension/icu/third_party/icu/common/ulist.cpp" +#include "extension/icu/third_party/icu/common/ustack.cpp" -#include "extension/icu/third_party/icu/common/uarrsort.cpp" +#include "extension/icu/third_party/icu/common/filterednormalizer2.cpp" -#include "extension/icu/third_party/icu/common/ustack.cpp" +#include "extension/icu/third_party/icu/common/usc_impl.cpp" -#include "extension/icu/third_party/icu/common/characterproperties.cpp" +#include "extension/icu/third_party/icu/common/resbund.cpp" -#include "extension/icu/third_party/icu/common/ubidiln.cpp" +#include "extension/icu/third_party/icu/common/util_props.cpp" -#include "extension/icu/third_party/icu/common/udataswp.cpp" +#include "extension/icu/third_party/icu/common/locbased.cpp" -#include "extension/icu/third_party/icu/common/locdispnames.cpp" +#include "extension/icu/third_party/icu/common/resource.cpp" -#include "extension/icu/third_party/icu/common/unisetspan.cpp" +#include "extension/icu/third_party/icu/common/uchriter.cpp" -#include "extension/icu/third_party/icu/common/uinvchar.cpp" +#include "extension/icu/third_party/icu/common/usetiter.cpp" -#include "extension/icu/third_party/icu/common/ucln_cmn.cpp" +#include "extension/icu/third_party/icu/common/edits.cpp" -#include "extension/icu/third_party/icu/common/uinit.cpp" +#include "extension/icu/third_party/icu/common/ucasemap.cpp" -#include "extension/icu/third_party/icu/common/localeprioritylist.cpp" +#include "extension/icu/third_party/icu/common/stringtriebuilder.cpp" -#include "extension/icu/third_party/icu/common/unifilt.cpp" +#include "extension/icu/third_party/icu/common/normlzr.cpp" -#include "extension/icu/third_party/icu/common/ubidiwrt.cpp" +#include "extension/icu/third_party/icu/common/ustr_wcs.cpp" -#include "extension/icu/third_party/icu/common/fixedstring.cpp" +#include "extension/icu/third_party/icu/common/util.cpp" -#include "extension/icu/third_party/icu/common/umath.cpp" +#include "extension/icu/third_party/icu/common/uvectr64.cpp" -#include "extension/icu/third_party/icu/common/uenum.cpp" +#include "extension/icu/third_party/icu/common/appendable.cpp" -#include "extension/icu/third_party/icu/common/uset_props.cpp" +#include "extension/icu/third_party/icu/common/pluralmap.cpp" -#include "extension/icu/third_party/icu/common/unifunct.cpp" +#include "extension/icu/third_party/icu/common/ustrtrns.cpp" -#include "extension/icu/third_party/icu/common/errorcode.cpp" +#include "extension/icu/third_party/icu/common/ulist.cpp" #include "extension/icu/third_party/icu/common/uloc_tag.cpp" -#include "extension/icu/third_party/icu/common/ustrenum.cpp" +#include "extension/icu/third_party/icu/common/utrace.cpp" -#include "extension/icu/third_party/icu/common/parsepos.cpp" +#include "extension/icu/third_party/icu/common/ubidiwrt.cpp" -#include "extension/icu/third_party/icu/common/uset.cpp" +#include "extension/icu/third_party/icu/common/messagepattern.cpp" -#include "extension/icu/third_party/icu/common/cstring.cpp" +#include "extension/icu/third_party/icu/common/ucln_cmn.cpp" -#include "extension/icu/third_party/icu/common/ucasemap.cpp" +#include "extension/icu/third_party/icu/common/chariter.cpp" -#include "extension/icu/third_party/icu/common/uiter.cpp" +#include "extension/icu/third_party/icu/common/uarrsort.cpp" -#include "extension/icu/third_party/icu/common/lsr.cpp" +#include "extension/icu/third_party/icu/common/loclikely.cpp" -#include "extension/icu/third_party/icu/common/edits.cpp" +#include "extension/icu/third_party/icu/common/unorm.cpp" -#include "extension/icu/third_party/icu/common/emojiprops.cpp" +#include "extension/icu/third_party/icu/common/uinit.cpp" -#include "extension/icu/third_party/icu/common/stringtriebuilder.cpp" +#include "extension/icu/third_party/icu/common/propsvec.cpp" -#include "extension/icu/third_party/icu/common/uvectr64.cpp" +#include "extension/icu/third_party/icu/common/resbund_cnv.cpp" -#include "extension/icu/third_party/icu/common/resbund.cpp" +#include "extension/icu/third_party/icu/common/sharedobject.cpp" + +#include "extension/icu/third_party/icu/common/utrie_swap.cpp" #include "extension/icu/third_party/icu/common/ucharstrie.cpp" -#include "extension/icu/third_party/icu/common/filterednormalizer2.cpp" +#include "extension/icu/third_party/icu/common/uvectr32.cpp" -#include "extension/icu/third_party/icu/common/uchar.cpp" +#include "extension/icu/third_party/icu/common/stringpiece.cpp" -#include "extension/icu/third_party/icu/common/chariter.cpp" +#include "extension/icu/third_party/icu/common/unistr_props.cpp" -#include "extension/icu/third_party/icu/common/locid.cpp" +#include "extension/icu/third_party/icu/common/charstr.cpp" -#include "extension/icu/third_party/icu/common/ustrcase_locale.cpp" +#include "extension/icu/third_party/icu/common/lsr.cpp" -#include "extension/icu/third_party/icu/common/unistr_case.cpp" +#include "extension/icu/third_party/icu/common/umath.cpp" -#include "extension/icu/third_party/icu/common/sharedobject.cpp" +#include "extension/icu/third_party/icu/common/dtintrv.cpp" -#include "extension/icu/third_party/icu/common/simpleformatter.cpp" +#include "extension/icu/third_party/icu/common/locdispnames.cpp" -#include "extension/icu/third_party/icu/common/util.cpp" +#include "extension/icu/third_party/icu/common/ucat.cpp" -#include "extension/icu/third_party/icu/common/normalizer2impl.cpp" +#include "extension/icu/third_party/icu/common/uscript.cpp" -#include "extension/icu/third_party/icu/common/uprops.cpp" +#include "extension/icu/third_party/icu/common/fixedstring.cpp" -#include "extension/icu/third_party/icu/common/patternprops.cpp" +#include "extension/icu/third_party/icu/common/umutex.cpp" -#include "extension/icu/third_party/icu/common/locdspnm.cpp" +#include "extension/icu/third_party/icu/common/normalizer2impl.cpp" -#include "extension/icu/third_party/icu/common/ucharstrieiterator.cpp" +#include "extension/icu/third_party/icu/common/udatamem.cpp" -#include "extension/icu/third_party/icu/common/messagepattern.cpp" +#include "extension/icu/third_party/icu/common/unistr_case_locale.cpp" + +#include "extension/icu/third_party/icu/common/bytesinkutil.cpp" #include "extension/icu/third_party/icu/common/bytestrie.cpp" -#include "extension/icu/third_party/icu/common/uscript.cpp" +#include "extension/icu/third_party/icu/common/udata.cpp" -#include "extension/icu/third_party/icu/common/utf_impl.cpp" +#include "extension/icu/third_party/icu/common/cstring.cpp" -#include "extension/icu/third_party/icu/common/uniset_closure.cpp" +#include "extension/icu/third_party/icu/common/utext.cpp" -#include "extension/icu/third_party/icu/common/bmpset.cpp" +#include "extension/icu/third_party/icu/common/uniset.cpp" -#include "extension/icu/third_party/icu/common/pluralmap.cpp" +#include "extension/icu/third_party/icu/common/localeprioritylist.cpp" -#include "extension/icu/third_party/icu/common/ucat.cpp" +#include "extension/icu/third_party/icu/common/icudataver.cpp" -#include "extension/icu/third_party/icu/common/udata.cpp" +#include "extension/icu/third_party/icu/common/ubidi.cpp" -#include "extension/icu/third_party/icu/common/normlzr.cpp" +#include "extension/icu/third_party/icu/common/uiter.cpp" -#include "extension/icu/third_party/icu/common/ustr_wcs.cpp" +#include "extension/icu/third_party/icu/common/parsepos.cpp" -#include "extension/icu/third_party/icu/common/locbased.cpp" +#include "extension/icu/third_party/icu/common/unistr_case.cpp" -#include "extension/icu/third_party/icu/common/usetiter.cpp" +#include "extension/icu/third_party/icu/common/uenum.cpp" -#include "extension/icu/third_party/icu/common/localematcher.cpp" +#include "extension/icu/third_party/icu/common/uloc_keytype.cpp" -#include "extension/icu/third_party/icu/common/charstr.cpp" +#include "extension/icu/third_party/icu/common/uhash_us.cpp" -#include "extension/icu/third_party/icu/common/bytesinkutil.cpp" +#include "extension/icu/third_party/icu/common/localematcher.cpp" -#include "extension/icu/third_party/icu/common/resbund_cnv.cpp" +#include "extension/icu/third_party/icu/common/ucol_swp.cpp" + +#include "extension/icu/third_party/icu/common/ustrfmt.cpp" #include "extension/icu/third_party/icu/common/bytestrieiterator.cpp" -#include "extension/icu/third_party/icu/common/icudataver.cpp" +#include "extension/icu/third_party/icu/common/ucharstrieiterator.cpp" -#include "extension/icu/third_party/icu/common/resource.cpp" +#include "extension/icu/third_party/icu/common/unifilt.cpp" -#include "extension/icu/third_party/icu/common/ucol_swp.cpp" +#include "extension/icu/third_party/icu/common/uinvchar.cpp" -#include "extension/icu/third_party/icu/common/ruleiter.cpp" +#include "extension/icu/third_party/icu/common/schriter.cpp" -#include "extension/icu/third_party/icu/common/udatamem.cpp" +#include "extension/icu/third_party/icu/common/uniset_closure.cpp" -#include "extension/icu/third_party/icu/common/ures_cnv.cpp" +#include "extension/icu/third_party/icu/common/cmemory.cpp" -#include "extension/icu/third_party/icu/common/ushape.cpp" +#include "extension/icu/third_party/icu/common/utypes.cpp" -#include "extension/icu/third_party/icu/common/propsvec.cpp" +#include "extension/icu/third_party/icu/common/ustrenum.cpp" -#include "extension/icu/third_party/icu/common/usc_impl.cpp" +#include "extension/icu/third_party/icu/common/ustrcase_locale.cpp" -#include "extension/icu/third_party/icu/common/util_props.cpp" +#include "extension/icu/third_party/icu/common/ures_cnv.cpp" -#include "extension/icu/third_party/icu/common/uhash_us.cpp" +#include "extension/icu/third_party/icu/common/normalizer2.cpp" -#include "extension/icu/third_party/icu/common/unistr_props.cpp" +#include "extension/icu/third_party/icu/common/unisetspan.cpp" -#include "extension/icu/third_party/icu/common/ucmndata.cpp" +#include "extension/icu/third_party/icu/common/uset.cpp" -#include "extension/icu/third_party/icu/common/ustrfmt.cpp" +#include "extension/icu/third_party/icu/common/ucurr.cpp" -#include "extension/icu/third_party/icu/common/uchriter.cpp" +#include "extension/icu/third_party/icu/common/locdspnm.cpp" -#include "extension/icu/third_party/icu/common/caniter.cpp" +#include "extension/icu/third_party/icu/common/unifunct.cpp" -#include "extension/icu/third_party/icu/common/locresdata.cpp" +#include "extension/icu/third_party/icu/common/udataswp.cpp" -#include "extension/icu/third_party/icu/common/utrace.cpp" +#include "extension/icu/third_party/icu/common/bmpset.cpp" -#include "extension/icu/third_party/icu/common/ubidi.cpp" +#include "extension/icu/third_party/icu/common/errorcode.cpp" + +#include "extension/icu/third_party/icu/common/emojiprops.cpp" + +#include "extension/icu/third_party/icu/common/unistr.cpp" diff --git a/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp b/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp index 8171e1d4a..4a3d5f324 100644 --- a/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +++ b/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp @@ -1,182 +1,182 @@ -#include "extension/icu/third_party/icu/i18n/tztrans.cpp" +#include "extension/icu/third_party/icu/i18n/tznames_impl.cpp" -#include "extension/icu/third_party/icu/i18n/collationruleparser.cpp" +#include "extension/icu/third_party/icu/i18n/ucal.cpp" -#include "extension/icu/third_party/icu/i18n/basictz.cpp" +#include "extension/icu/third_party/icu/i18n/zonemeta.cpp" -#include "extension/icu/third_party/icu/i18n/utmscale.cpp" +#include "extension/icu/third_party/icu/i18n/ucol_sit.cpp" -#include "extension/icu/third_party/icu/i18n/tzrule.cpp" +#include "extension/icu/third_party/icu/i18n/collationtailoring.cpp" -#include "extension/icu/third_party/icu/i18n/listformatter.cpp" +#include "extension/icu/third_party/icu/i18n/dcfmtsym.cpp" #include "extension/icu/third_party/icu/i18n/coleitr.cpp" -#include "extension/icu/third_party/icu/i18n/collationdata.cpp" +#include "extension/icu/third_party/icu/i18n/units_converter.cpp" -#include "extension/icu/third_party/icu/i18n/ucoleitr.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatareader.cpp" -#include "extension/icu/third_party/icu/i18n/sortkey.cpp" +#include "extension/icu/third_party/icu/i18n/measunit.cpp" -#include "extension/icu/third_party/icu/i18n/dangical.cpp" +#include "extension/icu/third_party/icu/i18n/ztrans.cpp" -#include "extension/icu/third_party/icu/i18n/uregion.cpp" +#include "extension/icu/third_party/icu/i18n/number_affixutils.cpp" -#include "extension/icu/third_party/icu/i18n/udateintervalformat.cpp" +#include "extension/icu/third_party/icu/i18n/tznames.cpp" -#include "extension/icu/third_party/icu/i18n/ucln_in.cpp" +#include "extension/icu/third_party/icu/i18n/udatpg.cpp" #include "extension/icu/third_party/icu/i18n/formattedval_iterimpl.cpp" -#include "extension/icu/third_party/icu/i18n/collationsettings.cpp" - -#include "extension/icu/third_party/icu/i18n/rbtz.cpp" - -#include "extension/icu/third_party/icu/i18n/collationtailoring.cpp" - -#include "extension/icu/third_party/icu/i18n/tznames_impl.cpp" +#include "extension/icu/third_party/icu/i18n/ufieldpositer.cpp" -#include "extension/icu/third_party/icu/i18n/currunit.cpp" +#include "extension/icu/third_party/icu/i18n/collationfastlatin.cpp" -#include "extension/icu/third_party/icu/i18n/region.cpp" +#include "extension/icu/third_party/icu/i18n/tzfmt.cpp" -#include "extension/icu/third_party/icu/i18n/ulocdata.cpp" +#include "extension/icu/third_party/icu/i18n/udateintervalformat.cpp" -#include "extension/icu/third_party/icu/i18n/format.cpp" +#include "extension/icu/third_party/icu/i18n/fphdlimp.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatawriter.cpp" +#include "extension/icu/third_party/icu/i18n/sortkey.cpp" -#include "extension/icu/third_party/icu/i18n/collationkeys.cpp" +#include "extension/icu/third_party/icu/i18n/unum.cpp" -#include "extension/icu/third_party/icu/i18n/formattedvalue.cpp" +#include "extension/icu/third_party/icu/i18n/collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/decContext.cpp" +#include "extension/icu/third_party/icu/i18n/formatted_string_builder.cpp" -#include "extension/icu/third_party/icu/i18n/reldtfmt.cpp" +#include "extension/icu/third_party/icu/i18n/collationfastlatinbuilder.cpp" -#include "extension/icu/third_party/icu/i18n/standardplural.cpp" +#include "extension/icu/third_party/icu/i18n/astro.cpp" -#include "extension/icu/third_party/icu/i18n/alphaindex.cpp" +#include "extension/icu/third_party/icu/i18n/region.cpp" -#include "extension/icu/third_party/icu/i18n/datefmt.cpp" +#include "extension/icu/third_party/icu/i18n/tmutamt.cpp" -#include "extension/icu/third_party/icu/i18n/uitercollationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/udat.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatareader.cpp" +#include "extension/icu/third_party/icu/i18n/displayoptions.cpp" -#include "extension/icu/third_party/icu/i18n/number_notation.cpp" +#include "extension/icu/third_party/icu/i18n/uregion.cpp" -#include "extension/icu/third_party/icu/i18n/dtrule.cpp" +#include "extension/icu/third_party/icu/i18n/listformatter.cpp" -#include "extension/icu/third_party/icu/i18n/unum.cpp" +#include "extension/icu/third_party/icu/i18n/rulebasedcollator.cpp" -#include "extension/icu/third_party/icu/i18n/ulistformatter.cpp" +#include "extension/icu/third_party/icu/i18n/collationbuilder.cpp" -#include "extension/icu/third_party/icu/i18n/tmutamt.cpp" +#include "extension/icu/third_party/icu/i18n/vzone.cpp" -#include "extension/icu/third_party/icu/i18n/bocsu.cpp" +#include "extension/icu/third_party/icu/i18n/simpletz.cpp" #include "extension/icu/third_party/icu/i18n/utf16collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/tmunit.cpp" +#include "extension/icu/third_party/icu/i18n/reldtfmt.cpp" -#include "extension/icu/third_party/icu/i18n/fpositer.cpp" +#include "extension/icu/third_party/icu/i18n/unumsys.cpp" -#include "extension/icu/third_party/icu/i18n/collationfastlatinbuilder.cpp" +#include "extension/icu/third_party/icu/i18n/uitercollationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/number_modifiers.cpp" +#include "extension/icu/third_party/icu/i18n/collation.cpp" -#include "extension/icu/third_party/icu/i18n/collationcompare.cpp" +#include "extension/icu/third_party/icu/i18n/rbtz.cpp" -#include "extension/icu/third_party/icu/i18n/measunit.cpp" +#include "extension/icu/third_party/icu/i18n/erarules.cpp" -#include "extension/icu/third_party/icu/i18n/astro.cpp" +#include "extension/icu/third_party/icu/i18n/olsontz.cpp" -#include "extension/icu/third_party/icu/i18n/udat.cpp" +#include "extension/icu/third_party/icu/i18n/ulistformatter.cpp" -#include "extension/icu/third_party/icu/i18n/utf8collationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/formattedvalue.cpp" -#include "extension/icu/third_party/icu/i18n/selfmt.cpp" +#include "extension/icu/third_party/icu/i18n/collationdata.cpp" -#include "extension/icu/third_party/icu/i18n/collationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/bocsu.cpp" -#include "extension/icu/third_party/icu/i18n/tzfmt.cpp" +#include "extension/icu/third_party/icu/i18n/fpositer.cpp" -#include "extension/icu/third_party/icu/i18n/units_converter.cpp" +#include "extension/icu/third_party/icu/i18n/currunit.cpp" -#include "extension/icu/third_party/icu/i18n/rulebasedcollator.cpp" +#include "extension/icu/third_party/icu/i18n/decContext.cpp" -#include "extension/icu/third_party/icu/i18n/dcfmtsym.cpp" +#include "extension/icu/third_party/icu/i18n/collationsets.cpp" -#include "extension/icu/third_party/icu/i18n/dtitvinf.cpp" +#include "extension/icu/third_party/icu/i18n/measure.cpp" -#include "extension/icu/third_party/icu/i18n/collationfcd.cpp" +#include "extension/icu/third_party/icu/i18n/format.cpp" -#include "extension/icu/third_party/icu/i18n/udatpg.cpp" +#include "extension/icu/third_party/icu/i18n/number_padding.cpp" -#include "extension/icu/third_party/icu/i18n/scientificnumberformatter.cpp" +#include "extension/icu/third_party/icu/i18n/alphaindex.cpp" -#include "extension/icu/third_party/icu/i18n/coll.cpp" +#include "extension/icu/third_party/icu/i18n/basictz.cpp" -#include "extension/icu/third_party/icu/i18n/unumsys.cpp" +#include "extension/icu/third_party/icu/i18n/umsg.cpp" -#include "extension/icu/third_party/icu/i18n/displayoptions.cpp" +#include "extension/icu/third_party/icu/i18n/dtrule.cpp" -#include "extension/icu/third_party/icu/i18n/smpdtfst.cpp" +#include "extension/icu/third_party/icu/i18n/collationfcd.cpp" -#include "extension/icu/third_party/icu/i18n/zrule.cpp" +#include "extension/icu/third_party/icu/i18n/number_notation.cpp" -#include "extension/icu/third_party/icu/i18n/collationbuilder.cpp" +#include "extension/icu/third_party/icu/i18n/ucln_in.cpp" -#include "extension/icu/third_party/icu/i18n/vzone.cpp" +#include "extension/icu/third_party/icu/i18n/tzrule.cpp" -#include "extension/icu/third_party/icu/i18n/ufieldpositer.cpp" +#include "extension/icu/third_party/icu/i18n/smpdtfst.cpp" -#include "extension/icu/third_party/icu/i18n/ucol_sit.cpp" +#include "extension/icu/third_party/icu/i18n/ulocdata.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatabuilder.cpp" +#include "extension/icu/third_party/icu/i18n/collationruleparser.cpp" -#include "extension/icu/third_party/icu/i18n/collationfastlatin.cpp" +#include "extension/icu/third_party/icu/i18n/scientificnumberformatter.cpp" -#include "extension/icu/third_party/icu/i18n/number_padding.cpp" +#include "extension/icu/third_party/icu/i18n/utf8collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/erarules.cpp" +#include "extension/icu/third_party/icu/i18n/tztrans.cpp" + +#include "extension/icu/third_party/icu/i18n/zrule.cpp" #include "extension/icu/third_party/icu/i18n/collationweights.cpp" -#include "extension/icu/third_party/icu/i18n/collationrootelements.cpp" +#include "extension/icu/third_party/icu/i18n/number_modifiers.cpp" -#include "extension/icu/third_party/icu/i18n/measure.cpp" +#include "extension/icu/third_party/icu/i18n/tmunit.cpp" -#include "extension/icu/third_party/icu/i18n/collationsets.cpp" +#include "extension/icu/third_party/icu/i18n/dtitvinf.cpp" -#include "extension/icu/third_party/icu/i18n/ucal.cpp" +#include "extension/icu/third_party/icu/i18n/collationcompare.cpp" -#include "extension/icu/third_party/icu/i18n/number_decimfmtprops.cpp" +#include "extension/icu/third_party/icu/i18n/currfmt.cpp" -#include "extension/icu/third_party/icu/i18n/umsg.cpp" +#include "extension/icu/third_party/icu/i18n/selfmt.cpp" -#include "extension/icu/third_party/icu/i18n/tznames.cpp" +#include "extension/icu/third_party/icu/i18n/standardplural.cpp" #include "extension/icu/third_party/icu/i18n/curramt.cpp" -#include "extension/icu/third_party/icu/i18n/simpletz.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatawriter.cpp" -#include "extension/icu/third_party/icu/i18n/number_affixutils.cpp" +#include "extension/icu/third_party/icu/i18n/ucoleitr.cpp" -#include "extension/icu/third_party/icu/i18n/zonemeta.cpp" +#include "extension/icu/third_party/icu/i18n/number_decimfmtprops.cpp" -#include "extension/icu/third_party/icu/i18n/olsontz.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatabuilder.cpp" -#include "extension/icu/third_party/icu/i18n/ztrans.cpp" +#include "extension/icu/third_party/icu/i18n/datefmt.cpp" -#include "extension/icu/third_party/icu/i18n/fphdlimp.cpp" +#include "extension/icu/third_party/icu/i18n/utmscale.cpp" #include "extension/icu/third_party/icu/i18n/gender.cpp" -#include "extension/icu/third_party/icu/i18n/currfmt.cpp" +#include "extension/icu/third_party/icu/i18n/collationkeys.cpp" -#include "extension/icu/third_party/icu/i18n/formatted_string_builder.cpp" +#include "extension/icu/third_party/icu/i18n/dangical.cpp" -#include "extension/icu/third_party/icu/i18n/collation.cpp" +#include "extension/icu/third_party/icu/i18n/collationrootelements.cpp" + +#include "extension/icu/third_party/icu/i18n/coll.cpp" + +#include "extension/icu/third_party/icu/i18n/collationsettings.cpp" diff --git a/src/duckdb/ub_extension_json_json_functions.cpp b/src/duckdb/ub_extension_json_json_functions.cpp index 1523a5983..d4615dc86 100644 --- a/src/duckdb/ub_extension_json_json_functions.cpp +++ b/src/duckdb/ub_extension_json_json_functions.cpp @@ -1,46 +1,46 @@ -#include "extension/json/json_functions/json_contains.cpp" +#include "extension/json/json_functions/json_valid.cpp" #include "extension/json/json_functions/read_json.cpp" -#include "extension/json/json_functions/json_extract.cpp" +#include "extension/json/json_functions/json_transform.cpp" -#include "extension/json/json_functions/json_type.cpp" +#include "extension/json/json_functions/json_extract.cpp" -#include "extension/json/json_functions/json_valid.cpp" +#include "extension/json/json_functions/json_exists.cpp" -#include "extension/json/json_functions/json_transform.cpp" +#include "extension/json/json_functions/json_merge_patch_diff.cpp" -#include "extension/json/json_functions/json_keys.cpp" +#include "extension/json/json_functions/json_serialize_sql.cpp" -#include "extension/json/json_functions/copy_json.cpp" +#include "extension/json/json_functions/json_serialize_plan.cpp" -#include "extension/json/json_functions/json_table_in_out.cpp" +#include "extension/json/json_functions/json_pretty.cpp" -#include "extension/json/json_functions/json_serialize_plan.cpp" +#include "extension/json/json_functions/json_contains.cpp" -#include "extension/json/json_functions/json_strip_nulls.cpp" +#include "extension/json/json_functions/json_type.cpp" -#include "extension/json/json_functions/json_merge_patch_diff.cpp" +#include "extension/json/json_functions/copy_json.cpp" -#include "extension/json/json_functions/json_exists.cpp" +#include "extension/json/json_functions/json_table_in_out.cpp" -#include "extension/json/json_functions/json_structure.cpp" +#include "extension/json/json_functions/json_value.cpp" -#include "extension/json/json_functions/json_pretty.cpp" +#include "extension/json/json_functions/json_array_length.cpp" -#include "extension/json/json_functions/read_json_objects.cpp" +#include "extension/json/json_functions/json_normalize.cpp" #include "extension/json/json_functions/json_create.cpp" #include "extension/json/json_functions/json_deep_merge.cpp" -#include "extension/json/json_functions/json_serialize_sql.cpp" - -#include "extension/json/json_functions/json_value.cpp" +#include "extension/json/json_functions/json_structure.cpp" -#include "extension/json/json_functions/json_array_length.cpp" +#include "extension/json/json_functions/read_json_objects.cpp" -#include "extension/json/json_functions/json_normalize.cpp" +#include "extension/json/json_functions/json_strip_nulls.cpp" #include "extension/json/json_functions/json_merge_patch.cpp" +#include "extension/json/json_functions/json_keys.cpp" + diff --git a/src/duckdb/ub_extension_parquet_decoder.cpp b/src/duckdb/ub_extension_parquet_decoder.cpp index 5d625aaf8..997d85451 100644 --- a/src/duckdb/ub_extension_parquet_decoder.cpp +++ b/src/duckdb/ub_extension_parquet_decoder.cpp @@ -1,4 +1,6 @@ -#include "extension/parquet/decoder/rle_decoder.cpp" +#include "extension/parquet/decoder/delta_byte_array_decoder.cpp" + +#include "extension/parquet/decoder/delta_binary_packed_decoder.cpp" #include "extension/parquet/decoder/dictionary_decoder.cpp" @@ -6,7 +8,5 @@ #include "extension/parquet/decoder/byte_stream_split_decoder.cpp" -#include "extension/parquet/decoder/delta_binary_packed_decoder.cpp" - -#include "extension/parquet/decoder/delta_byte_array_decoder.cpp" +#include "extension/parquet/decoder/rle_decoder.cpp" diff --git a/src/duckdb/ub_extension_parquet_reader.cpp b/src/duckdb/ub_extension_parquet_reader.cpp index 28b599256..2a440cbb8 100644 --- a/src/duckdb/ub_extension_parquet_reader.cpp +++ b/src/duckdb/ub_extension_parquet_reader.cpp @@ -1,14 +1,14 @@ -#include "extension/parquet/reader/struct_column_reader.cpp" +#include "extension/parquet/reader/string_column_reader.cpp" -#include "extension/parquet/reader/list_column_reader.cpp" +#include "extension/parquet/reader/expression_column_reader.cpp" -#include "extension/parquet/reader/decimal_column_reader.cpp" +#include "extension/parquet/reader/row_number_column_reader.cpp" -#include "extension/parquet/reader/variant_column_reader.cpp" +#include "extension/parquet/reader/list_column_reader.cpp" -#include "extension/parquet/reader/string_column_reader.cpp" +#include "extension/parquet/reader/struct_column_reader.cpp" -#include "extension/parquet/reader/expression_column_reader.cpp" +#include "extension/parquet/reader/variant_column_reader.cpp" -#include "extension/parquet/reader/row_number_column_reader.cpp" +#include "extension/parquet/reader/decimal_column_reader.cpp" diff --git a/src/duckdb/ub_extension_parquet_writer.cpp b/src/duckdb/ub_extension_parquet_writer.cpp index e1d3beb0f..4d1eadb19 100644 --- a/src/duckdb/ub_extension_parquet_writer.cpp +++ b/src/duckdb/ub_extension_parquet_writer.cpp @@ -1,16 +1,16 @@ +#include "extension/parquet/writer/array_column_writer.cpp" + #include "extension/parquet/writer/boolean_column_writer.cpp" #include "extension/parquet/writer/struct_column_writer.cpp" -#include "extension/parquet/writer/array_column_writer.cpp" +#include "extension/parquet/writer/variant_column_writer.cpp" -#include "extension/parquet/writer/enum_column_writer.cpp" +#include "extension/parquet/writer/primitive_column_writer.cpp" #include "extension/parquet/writer/list_column_writer.cpp" -#include "extension/parquet/writer/decimal_column_writer.cpp" - -#include "extension/parquet/writer/primitive_column_writer.cpp" +#include "extension/parquet/writer/enum_column_writer.cpp" -#include "extension/parquet/writer/variant_column_writer.cpp" +#include "extension/parquet/writer/decimal_column_writer.cpp" diff --git a/src/duckdb/ub_extension_parquet_writer_variant.cpp b/src/duckdb/ub_extension_parquet_writer_variant.cpp index 6e4563d1e..61cb37a96 100644 --- a/src/duckdb/ub_extension_parquet_writer_variant.cpp +++ b/src/duckdb/ub_extension_parquet_writer_variant.cpp @@ -1,4 +1,4 @@ -#include "extension/parquet/writer/variant/convert_variant.cpp" - #include "extension/parquet/writer/variant/analyze_variant.cpp" +#include "extension/parquet/writer/variant/convert_variant.cpp" + diff --git a/src/duckdb/ub_src_planner_binder_query_node.cpp b/src/duckdb/ub_src_planner_binder_query_node.cpp index 1cac9b789..0420b24f3 100644 --- a/src/duckdb/ub_src_planner_binder_query_node.cpp +++ b/src/duckdb/ub_src_planner_binder_query_node.cpp @@ -10,6 +10,8 @@ #include "src/planner/binder/query_node/bind_table_macro_node.cpp" +#include "src/planner/binder/query_node/bind_trigger_expansion.cpp" + #include "src/planner/binder/query_node/plan_query_node.cpp" #include "src/planner/binder/query_node/plan_select_node.cpp" From 2c3d27ac7b334b762d8037fc11d1e9658527acc9 Mon Sep 17 00:00:00 2001 From: DuckDB Labs GitHub Bot Date: Sat, 13 Jun 2026 18:44:59 +0000 Subject: [PATCH 2/2] Update vendored DuckDB sources to ccbdf9f7c7 --- CMakeLists.txt | 1 + .../aggregate/distributive/arg_min_max.cpp | 245 +- .../aggregate/distributive/product.cpp | 6 +- .../core_functions/aggregate/holistic/mad.cpp | 14 +- .../aggregate/holistic/quantile.cpp | 102 +- .../core_functions/aggregate/nested/list.cpp | 170 +- .../aggregate/quantile_state.hpp | 117 +- .../extension/parquet/parquet_writer.cpp | 1 + src/duckdb/src/common/enum_util.cpp | 72 +- src/duckdb/src/common/extra_type_info.cpp | 48 +- src/duckdb/src/common/tree_renderer.cpp | 94 +- .../tree_renderer/graphviz_tree_renderer.cpp | 9 + .../tree_renderer/html_tree_renderer.cpp | 9 + .../tree_renderer/json_tree_renderer.cpp | 12 + .../tree_renderer/mermaid_tree_renderer.cpp | 8 + .../tree_renderer/text_tree_renderer.cpp | 29 + src/duckdb/src/common/types.cpp | 360 +-- src/duckdb/src/common/types/list_segment.cpp | 411 ++- .../persistent/physical_copy_to_file.cpp | 10 + .../src/execution/physical_operator.cpp | 6 +- .../execution/physical_plan/plan_explain.cpp | 6 +- .../aggregate/distributive/decimal_avg.cpp | 170 ++ .../aggregate/distributive/first_last_any.cpp | 117 +- .../aggregate/distributive/minmax.cpp | 73 +- .../aggregate/sorted_aggregate_function.cpp | 428 +-- .../src/function/cast/cast_function_set.cpp | 24 +- .../src/function/combine_types_rules.cpp | 359 +++ src/duckdb/src/function/copy_function.cpp | 7 +- src/duckdb/src/function/function_list.cpp | 2 + .../src/function/pragma/pragma_functions.cpp | 1 - .../scalar/system/aggregate_export.cpp | 255 +- .../scalar/variant/variant_array_length.cpp | 91 + .../scalar/variant/variant_exists.cpp | 68 +- .../function/scalar/variant/variant_keys.cpp | 88 +- .../function/scalar/variant/variant_utils.cpp | 34 - .../function/table/system/duckdb_metrics.cpp | 2 +- .../table/system/enable_profiling.cpp | 6 +- .../function/table/version/pragma_version.cpp | 6 +- .../src/include/duckdb/common/enum_util.hpp | 24 +- .../duckdb/common/enums/explain_format.hpp | 17 - .../duckdb/common/enums/profiler_format.hpp | 17 - .../include/duckdb/common/extra_type_info.hpp | 4 + .../src/include/duckdb/common/render_tree.hpp | 2 +- .../include/duckdb/common/tree_renderer.hpp | 28 +- .../tree_renderer/graphviz_tree_renderer.hpp | 4 +- .../tree_renderer/html_tree_renderer.hpp | 4 +- .../tree_renderer/json_tree_renderer.hpp | 6 +- .../tree_renderer/mermaid_tree_renderer.hpp | 4 +- .../tree_renderer/text_tree_renderer.hpp | 24 +- .../tree_renderer/yaml_tree_renderer.hpp | 2 +- .../duckdb/common/types/list_segment.hpp | 31 +- .../helper/physical_explain_analyze.hpp | 9 +- .../duckdb/execution/physical_operator.hpp | 4 +- .../aggregate/distributive_function_utils.hpp | 8 +- .../aggregate/distributive_functions.hpp | 10 + .../function/aggregate/list_aggregate.hpp | 121 + .../function/aggregate/sort_key_helpers.hpp | 7 +- .../duckdb/function/aggregate_function.hpp | 81 +- .../duckdb/function/aggregate_state.hpp | 1 + .../function/aggregate_state_layout.hpp | 371 ++- .../function/cast/cast_function_set.hpp | 13 + .../duckdb/function/combine_types_rule.hpp | 39 + .../include/duckdb/function/copy_function.hpp | 5 +- .../src/include/duckdb/function/function.hpp | 15 + .../function/scalar/variant_functions.hpp | 10 + .../function/scalar/variant_path_function.hpp | 115 + .../duckdb/function/scalar/variant_utils.hpp | 8 - .../duckdb/function/scalar_function.hpp | 15 - .../src/include/duckdb/main/client_config.hpp | 13 +- .../src/include/duckdb/main/connection.hpp | 7 +- .../main/extension/extension_loader.hpp | 5 +- .../main/{ => profiler}/gathered_metrics.hpp | 5 +- .../main/{ => profiler}/metric_info.hpp | 2 +- .../duckdb/main/{ => profiler}/metrics.hpp | 2 +- .../main/{ => profiler}/metrics_manager.hpp | 4 +- .../main/profiler/profiler_print_format.hpp | 64 + .../main/{ => profiler}/profiling_node.hpp | 4 +- .../main/{ => profiler}/profiling_utils.hpp | 6 +- .../include/duckdb/main/query_profiler.hpp | 35 +- .../src/include/duckdb/main/relation.hpp | 2 +- .../duckdb/main/relation/explain_relation.hpp | 4 +- .../src/include/duckdb/main/settings.hpp | 32 +- .../duckdb/optimizer/unnest_rewriter.hpp | 9 + .../duckdb/parser/peg/inlined_grammar.hpp | 47 +- .../peg/transformer/peg_transformer.hpp | 728 +++-- .../parser/statement/explain_statement.hpp | 6 +- .../duckdb/planner/logical_operator.hpp | 4 +- .../planner/operator/logical_explain.hpp | 4 +- src/duckdb/src/main/client_context.cpp | 1 - src/duckdb/src/main/config.cpp | 9 +- src/duckdb/src/main/connection.cpp | 5 +- src/duckdb/src/main/database.cpp | 2 +- .../src/main/extension/extension_loader.cpp | 6 +- .../main/{ => profiler}/gathered_metrics.cpp | 4 +- .../main/{ => profiler}/metrics_manager.cpp | 4 +- .../main/{ => profiler}/profiling_utils.cpp | 2 +- src/duckdb/src/main/query_profiler.cpp | 173 +- src/duckdb/src/main/relation.cpp | 2 +- .../src/main/relation/explain_relation.cpp | 2 +- .../src/main/settings/custom_settings.cpp | 116 +- src/duckdb/src/optimizer/unnest_rewriter.cpp | 530 +++- .../transformer/peg_transformer_factory.cpp | 152 +- .../peg/transformer/transform_common.cpp | 3 +- .../peg/transformer/transform_explain.cpp | 26 +- .../peg/transformer/transform_generated.cpp | 2424 +++++++++++++++-- .../peg/transformer/transform_select.cpp | 2001 ++++++-------- .../parser/statement/explain_statement.cpp | 11 +- .../planner/binder/statement/bind_explain.cpp | 4 +- src/duckdb/src/planner/logical_operator.cpp | 6 +- .../src/planner/operator/logical_explain.cpp | 6 +- .../subquery/delim_join_cte_rewriter.cpp | 42 +- src/duckdb/src/storage/data_table.cpp | 2 +- .../storage/table/row_group_collection.cpp | 2 +- ...ion_core_functions_aggregate_algebraic.cpp | 4 +- ..._core_functions_aggregate_distributive.cpp | 16 +- ...sion_core_functions_aggregate_holistic.cpp | 4 +- ...ension_core_functions_aggregate_nested.cpp | 4 +- ...on_core_functions_aggregate_regression.cpp | 10 +- ...b_extension_core_functions_scalar_date.cpp | 18 +- ..._extension_core_functions_scalar_debug.cpp | 4 +- ...xtension_core_functions_scalar_generic.cpp | 16 +- ...b_extension_core_functions_scalar_list.cpp | 16 +- ...ub_extension_core_functions_scalar_map.cpp | 12 +- ...extension_core_functions_scalar_string.cpp | 48 +- ...extension_core_functions_scalar_struct.cpp | 6 +- ...b_extension_icu_third_party_icu_common.cpp | 216 +- .../ub_extension_icu_third_party_icu_i18n.cpp | 176 +- .../ub_extension_json_json_functions.cpp | 40 +- src/duckdb/ub_extension_parquet_decoder.cpp | 8 +- src/duckdb/ub_extension_parquet_reader.cpp | 14 +- src/duckdb/ub_extension_parquet_writer.cpp | 12 +- .../ub_extension_parquet_writer_variant.cpp | 4 +- src/duckdb/ub_src_function.cpp | 2 + ...ub_src_function_aggregate_distributive.cpp | 2 + src/duckdb/ub_src_function_scalar_variant.cpp | 2 + src/duckdb/ub_src_main.cpp | 6 - src/duckdb/ub_src_main_profiler.cpp | 6 + 137 files changed, 7483 insertions(+), 4141 deletions(-) create mode 100644 src/duckdb/src/function/aggregate/distributive/decimal_avg.cpp create mode 100644 src/duckdb/src/function/combine_types_rules.cpp create mode 100644 src/duckdb/src/function/scalar/variant/variant_array_length.cpp delete mode 100644 src/duckdb/src/include/duckdb/common/enums/explain_format.hpp delete mode 100644 src/duckdb/src/include/duckdb/common/enums/profiler_format.hpp create mode 100644 src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp create mode 100644 src/duckdb/src/include/duckdb/function/combine_types_rule.hpp create mode 100644 src/duckdb/src/include/duckdb/function/scalar/variant_path_function.hpp rename src/duckdb/src/include/duckdb/main/{ => profiler}/gathered_metrics.hpp (95%) rename src/duckdb/src/include/duckdb/main/{ => profiler}/metric_info.hpp (92%) rename src/duckdb/src/include/duckdb/main/{ => profiler}/metrics.hpp (99%) rename src/duckdb/src/include/duckdb/main/{ => profiler}/metrics_manager.hpp (93%) create mode 100644 src/duckdb/src/include/duckdb/main/profiler/profiler_print_format.hpp rename src/duckdb/src/include/duckdb/main/{ => profiler}/profiling_node.hpp (97%) rename src/duckdb/src/include/duckdb/main/{ => profiler}/profiling_utils.hpp (97%) rename src/duckdb/src/main/{ => profiler}/gathered_metrics.cpp (97%) rename src/duckdb/src/main/{ => profiler}/metrics_manager.cpp (97%) rename src/duckdb/src/main/{ => profiler}/profiling_utils.cpp (94%) create mode 100644 src/duckdb/ub_src_main_profiler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 649aebe80..6d0f82b47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -553,6 +553,7 @@ set(DUCKDB_SRC_FILES src/duckdb/ub_src_main.cpp src/duckdb/ub_src_main_buffered_data.cpp src/duckdb/ub_src_main_chunk_scan_state.cpp + src/duckdb/ub_src_main_profiler.cpp src/duckdb/ub_src_main_relation.cpp src/duckdb/ub_src_main_secret.cpp src/duckdb/ub_src_main_settings.cpp diff --git a/src/duckdb/extension/core_functions/aggregate/distributive/arg_min_max.cpp b/src/duckdb/extension/core_functions/aggregate/distributive/arg_min_max.cpp index ee6210754..b5123e61e 100644 --- a/src/duckdb/extension/core_functions/aggregate/distributive/arg_min_max.cpp +++ b/src/duckdb/extension/core_functions/aggregate/distributive/arg_min_max.cpp @@ -14,81 +14,104 @@ namespace duckdb { namespace { -struct ArgMinMaxStateBase { - ArgMinMaxStateBase() : is_initialized(false), arg_null(false), val_null(false) { - } - - template - static inline void CreateValue(T &value) { - } - - template - static inline void AssignValue(T &target, T new_value, AggregateInputData &aggregate_input_data) { +//! Assigns a value to the state, holding any extra information required to do so. +//! For non-string types this is empty and the assignment is a plain copy. +template +struct ArgMinMaxValueAssign { + void Assign(T &target, T new_value, AggregateInputData &aggregate_input_data) { target = new_value; } - - template - static inline void ReadValue(Vector &result, T &arg, T &target) { - target = arg; - } - - bool is_initialized; - bool arg_null; - bool val_null; }; -// Out-of-line specialisations +//! Strings are stored in the arena allocator, re-using the previous allocation when overwriting the value. +//! The allocation size is kept here - it is not part of the exported state. template <> -void ArgMinMaxStateBase::CreateValue(string_t &value) { - value = string_t(uint32_t(0)); -} - -template <> -void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value, AggregateInputData &aggregate_input_data) { - if (new_value.IsInlined()) { - target = new_value; - } else { - // non-inlined string, need to allocate space for it - auto len = new_value.GetSize(); - char *ptr; - if (!target.IsInlined() && target.GetSize() >= len) { - // Target has enough space, reuse ptr - ptr = target.GetPointer(); +struct ArgMinMaxValueAssign { + //! The size of the arena allocation for a non-inlined string value + uint32_t alloc_size; + + void Assign(string_t &target, string_t new_value, AggregateInputData &aggregate_input_data) { + if (new_value.IsInlined()) { + target = new_value; + alloc_size = 0; } else { - // Target might be too small, allocate - ptr = reinterpret_cast(aggregate_input_data.allocator.Allocate(len)); + auto len = UnsafeNumericCast(new_value.GetSize()); + char *ptr; + if (alloc_size >= len) { + ptr = target.GetDataWriteable(); + } else { + alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + ptr = char_ptr_cast(aggregate_input_data.allocator.Allocate(alloc_size)); + } + memcpy(ptr, new_value.GetData(), len); + target = string_t(ptr, len); } - memcpy(ptr, new_value.GetData(), len); - target = string_t(ptr, UnsafeNumericCast(len)); } +}; + +template +inline void ArgMinMaxReadValue(Vector &result, T &arg, T &target) { + target = arg; } template <> -void ArgMinMaxStateBase::ReadValue(Vector &result, string_t &arg, string_t &target) { +inline void ArgMinMaxReadValue(Vector &result, string_t &arg, string_t &target) { target = StringVector::AddStringOrBlob(result, arg); } +//! The aggregate state of arg_min/arg_max is nullable on two levels: the state itself is NULL when no row has been +//! recorded yet (is_set, the outer optional), while the recorded "arg" and "by" values can themselves be NULL (the +//! inner optionals). Valid exported states are e.g. NULL, {'arg': NULL, 'by': 42} and {'arg': 1, 'by': 42}. template -struct ArgMinMaxState : public ArgMinMaxStateBase { +struct ArgMinMaxState { using ARG_TYPE = A; using BY_TYPE = B; - ARG_TYPE arg; - BY_TYPE value; - - ArgMinMaxState() { - CreateValue(arg); - CreateValue(value); + static constexpr const char *STATE_NAMES[] = {"arg", "by"}; + //! Both values are exported with the corresponding runtime types of the bound function - e.g. the argument + //! can be a DATE or BLOB value instead of the physical type it is stored as + using STATE_TYPE = OptionalStateType>, + OptionalStateType>>>>; + + A arg; + //! Whether the recorded argument is valid (i.e. not NULL) + bool arg_is_valid; + B value; + //! Whether the recorded "by" value is valid (i.e. not NULL) + bool value_is_valid; + //! Whether the state has been set (i.e. we have recorded a row) + bool is_set; + //! Assignment helpers - these hold the arena allocation size for string values (and are empty otherwise), + //! and are not part of the exported state + ArgMinMaxValueAssign arg_assign; + ArgMinMaxValueAssign value_assign; + + void AssignArg(A input, AggregateInputData &aggregate_input_data) { + arg_assign.Assign(arg, input, aggregate_input_data); + } + void AssignBy(B input, AggregateInputData &aggregate_input_data) { + value_assign.Assign(value, input, aggregate_input_data); } }; +//! State for the vector arg_min/arg_max variants: the argument is stored as a binary sort key, while the "by" +//! value is typed - exported with the return type and the second argument type of the bound function respectively. +template +struct ArgMinMaxVectorState : ArgMinMaxState { + using STATE_TYPE = OptionalStateType>, + OptionalStateType>>>>; +}; + +//! State for the generic arg_min/arg_max variants: both the argument and the "by" value are stored as binary +//! sort keys. +template +struct ArgMinMaxSortKeyState : ArgMinMaxState { + using STATE_TYPE = OptionalStateType>, + OptionalStateType, ORDER>>>>; +}; + template struct ArgMinMaxBase { - template - static void Destroy(STATE &state, AggregateInputData &aggr_input_data) { - state.~STATE(); - } - template static void Assign(STATE &state, const A_TYPE &x, const B_TYPE &y, const bool x_null, const bool y_null, AggregateInputData &aggregate_input_data) { @@ -96,16 +119,18 @@ struct ArgMinMaxBase { const auto &bind_data = aggregate_input_data.bind_data->Cast(); if (bind_data.null_handling == ArgMinMaxNullHandling::IGNORE_ANY_NULL) { - STATE::template AssignValue(state.arg, x, aggregate_input_data); - STATE::template AssignValue(state.value, y, aggregate_input_data); + state.arg_is_valid = true; + state.value_is_valid = true; + state.AssignArg(x, aggregate_input_data); + state.AssignBy(y, aggregate_input_data); } else { - state.arg_null = x_null; - state.val_null = y_null; - if (!state.arg_null) { - STATE::template AssignValue(state.arg, x, aggregate_input_data); + state.arg_is_valid = !x_null; + state.value_is_valid = !y_null; + if (state.arg_is_valid) { + state.AssignArg(x, aggregate_input_data); } - if (!state.val_null) { - STATE::template AssignValue(state.value, y, aggregate_input_data); + if (state.value_is_valid) { + state.AssignBy(y, aggregate_input_data); } } } @@ -114,25 +139,25 @@ struct ArgMinMaxBase { static void Operation(STATE &state, const A_TYPE &x, const B_TYPE &y, AggregateBinaryInput &binary) { D_ASSERT(binary.input.bind_data); const auto &bind_data = binary.input.bind_data->Cast(); - if (!state.is_initialized) { + if (!state.is_set) { if (bind_data.null_handling == ArgMinMaxNullHandling::IGNORE_ANY_NULL && binary.left_mask.RowIsValid(binary.lidx) && binary.right_mask.RowIsValid(binary.ridx)) { Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx), !binary.right_mask.RowIsValid(binary.ridx), binary.input); - state.is_initialized = true; + state.is_set = true; return; } if (bind_data.null_handling == ArgMinMaxNullHandling::HANDLE_ARG_NULL && binary.right_mask.RowIsValid(binary.ridx)) { Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx), !binary.right_mask.RowIsValid(binary.ridx), binary.input); - state.is_initialized = true; + state.is_set = true; return; } if (bind_data.null_handling == ArgMinMaxNullHandling::HANDLE_ANY_NULL) { Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx), !binary.right_mask.RowIsValid(binary.ridx), binary.input); - state.is_initialized = true; + state.is_set = true; } } else { OP::template Execute(state, x, y, binary); @@ -145,7 +170,7 @@ struct ArgMinMaxBase { const auto &bind_data = binary.input.bind_data->Cast(); if (binary.right_mask.RowIsValid(binary.ridx) && - (state.val_null || COMPARATOR::Operation(y_data, state.value))) { + (!state.value_is_valid || COMPARATOR::Operation(y_data, state.value))) { if (bind_data.null_handling != ArgMinMaxNullHandling::IGNORE_ANY_NULL || binary.left_mask.RowIsValid(binary.lidx)) { Assign(state, x_data, y_data, !binary.left_mask.RowIsValid(binary.lidx), false, binary.input); @@ -155,23 +180,23 @@ struct ArgMinMaxBase { template static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) { - if (!source.is_initialized) { + if (!source.is_set) { return; } - if (!target.is_initialized || target.val_null || - (!source.val_null && COMPARATOR::Operation(source.value, target.value))) { - Assign(target, source.arg, source.value, source.arg_null, false, aggregate_input_data); - target.is_initialized = true; + if (!target.is_set || !target.value_is_valid || + (source.value_is_valid && COMPARATOR::Operation(source.value, target.value))) { + Assign(target, source.arg, source.value, !source.arg_is_valid, false, aggregate_input_data); + target.is_set = true; } } template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (!state.is_initialized || state.arg_null) { + if (!state.is_set || !state.arg_is_valid) { finalize_data.ReturnNull(); } else { - STATE::template ReadValue(finalize_data.result, state.arg, target); + ArgMinMaxReadValue(finalize_data.result, state.arg, target); } } @@ -188,6 +213,7 @@ struct ArgMinMaxBase { ExpressionBinder::PushCollation(context, arguments[1], arguments[1]->GetReturnType()); } function.GetArguments()[0] = arguments[0]->GetReturnType(); + function.GetArguments()[1] = arguments[1]->GetReturnType(); function.SetReturnType(arguments[0]->GetReturnType()); auto function_data = make_uniq(NULL_HANDLING); @@ -221,6 +247,8 @@ struct GenericArgMinMaxState { template struct VectorArgMinMaxBase : ArgMinMaxBase { + static constexpr OrderType ORDER = ORDER_TYPE; + template static void Update(Vector inputs[], AggregateInputData &aggregate_input_data, idx_t input_count, Vector &state_vector, idx_t count) { @@ -231,7 +259,6 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { UnifiedVectorFormat adata; arg.ToUnifiedFormat(adata); - using ARG_TYPE = typename STATE::ARG_TYPE; using BY_TYPE = typename STATE::BY_TYPE; auto &by = inputs[1]; UnifiedVectorFormat bdata; @@ -261,10 +288,11 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { const auto bidx = bdata.sel->get_index(i); if (!bdata.validity.RowIsValid(bidx)) { - if (bind_data.null_handling == ArgMinMaxNullHandling::HANDLE_ANY_NULL && !state.is_initialized) { - state.val_null = true; + if (bind_data.null_handling == ArgMinMaxNullHandling::HANDLE_ANY_NULL && !state.is_set) { + state.value_is_valid = false; if (!arg_null) { - state.is_initialized = true; + state.is_set = true; + state.arg_is_valid = true; if (&state == last_state) { assign_count--; } @@ -277,9 +305,10 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { const auto bval = bys[bidx]; - if (!state.is_initialized || state.val_null || COMPARATOR::template Operation(bval, state.value)) { - STATE::template AssignValue(state.value, bval, aggregate_input_data); - state.arg_null = arg_null; + if (!state.is_set || !state.value_is_valid || COMPARATOR::template Operation(bval, state.value)) { + state.AssignBy(bval, aggregate_input_data); + state.value_is_valid = true; + state.arg_is_valid = !arg_null; // micro-adaptivity: it is common we overwrite the same state repeatedly // e.g. when running arg_max(val, ts) and ts is sorted in ascending order // this check essentially says: @@ -292,7 +321,7 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { assign_sel[assign_count++] = UnsafeNumericCast(i); last_state = &state; } - state.is_initialized = true; + state.is_set = true; } } if (assign_count == 0) { @@ -311,32 +340,32 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { for (idx_t i = 0; i < assign_count; i++) { const auto sidx = sdata.sel->get_index(sel.get_index(i)); auto &state = *states[sidx]; - STATE::template AssignValue(state.arg, sort_key_data[i], aggregate_input_data); + state.AssignArg(sort_key_data[i], aggregate_input_data); } } template static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) { - if (!source.is_initialized) { + if (!source.is_set) { return; } - if (!target.is_initialized || target.val_null || - (!source.val_null && COMPARATOR::Operation(source.value, target.value))) { - target.val_null = source.val_null; - if (!target.val_null) { - STATE::template AssignValue(target.value, source.value, aggregate_input_data); + if (!target.is_set || !target.value_is_valid || + (source.value_is_valid && COMPARATOR::Operation(source.value, target.value))) { + target.value_is_valid = source.value_is_valid; + if (target.value_is_valid) { + target.AssignBy(source.value, aggregate_input_data); } - target.arg_null = source.arg_null; - if (!target.arg_null) { - STATE::template AssignValue(target.arg, source.arg, aggregate_input_data); + target.arg_is_valid = source.arg_is_valid; + if (target.arg_is_valid) { + target.AssignArg(source.arg, aggregate_input_data); } - target.is_initialized = true; + target.is_set = true; } } template static void Finalize(STATE &state, AggregateFinalizeData &finalize_data) { - if (!state.is_initialized || state.arg_null) { + if (!state.is_set || !state.arg_is_valid) { finalize_data.ReturnNull(); } else { CreateSortKeyHelpers::DecodeSortKey(state.arg, finalize_data.result, finalize_data.result_idx, @@ -353,6 +382,7 @@ struct VectorArgMinMaxBase : ArgMinMaxBase { ExpressionBinder::PushCollation(context, arguments[1], arguments[1]->GetReturnType()); } function.GetArguments()[0] = arguments[0]->GetReturnType(); + function.GetArguments()[1] = arguments[1]->GetReturnType(); function.SetReturnType(arguments[0]->GetReturnType()); auto function_data = make_uniq(NULL_HANDLING); @@ -374,26 +404,28 @@ bind_aggregate_function_t GetBindFunction(const ArgMinMaxNullHandling null_handl template AggregateFunction GetGenericArgMinMaxFunction(const ArgMinMaxNullHandling null_handling) { - using STATE = ArgMinMaxState; + using STATE = ArgMinMaxSortKeyState; auto bind = GetBindFunction(null_handling); - return AggregateFunction( + auto function = AggregateFunction( {LogicalType::ANY, LogicalType::ANY}, LogicalType::ANY, AggregateFunction::StateSize, - AggregateFunction::StateInitialize, OP::template Update, - AggregateFunction::StateCombine, AggregateFunction::StateVoidFinalize, nullptr, bind, - AggregateFunction::StateDestroy); + AggregateFunction::StateInitialize, OP::template Update, + AggregateFunction::StateCombine, AggregateFunction::StateVoidFinalize, nullptr, bind); + AggregateFunction::WireStructStateType(function); + return function; } template AggregateFunction GetVectorArgMinMaxFunctionInternal(const LogicalType &by_type, const LogicalType &type, const ArgMinMaxNullHandling null_handling) { #ifndef DUCKDB_SMALLER_BINARY - using STATE = ArgMinMaxState; + using STATE = ArgMinMaxVectorState; auto bind = GetBindFunction(null_handling); - return AggregateFunction({type, by_type}, type, AggregateFunction::StateSize, - AggregateFunction::StateInitialize, - OP::template Update, AggregateFunction::StateCombine, - AggregateFunction::StateVoidFinalize, nullptr, bind, - AggregateFunction::StateDestroy); + auto function = AggregateFunction({type, by_type}, type, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, OP::template Update, + AggregateFunction::StateCombine, + AggregateFunction::StateVoidFinalize, nullptr, bind); + AggregateFunction::WireStructStateType(function); + return function; #else auto function = GetGenericArgMinMaxFunction(null_handling); function.GetSignature().GetParameter(0).SetType(type); @@ -449,12 +481,7 @@ AggregateFunction GetArgMinMaxFunctionInternal(const LogicalType &by_type, const const ArgMinMaxNullHandling null_handling) { #ifndef DUCKDB_SMALLER_BINARY using STATE = ArgMinMaxState; - auto function = - AggregateFunction::BinaryAggregate( - type, by_type, type); - if (type.InternalType() == PhysicalType::VARCHAR || by_type.InternalType() == PhysicalType::VARCHAR) { - function.SetStateDestructorCallback(AggregateFunction::StateDestroy); - } + auto function = AggregateFunction::BinaryAggregate(type, by_type, type); function.SetBindCallback(GetBindFunction(null_handling)); #else auto function = GetGenericArgMinMaxFunction(null_handling); diff --git a/src/duckdb/extension/core_functions/aggregate/distributive/product.cpp b/src/duckdb/extension/core_functions/aggregate/distributive/product.cpp index 424d87b4b..caf7977be 100644 --- a/src/duckdb/extension/core_functions/aggregate/distributive/product.cpp +++ b/src/duckdb/extension/core_functions/aggregate/distributive/product.cpp @@ -4,6 +4,7 @@ #include "duckdb/common/vector_operations/vector_operations.hpp" #include "duckdb/planner/expression/bound_aggregate_expression.hpp" #include "duckdb/function/aggregate/distributive_function_utils.hpp" +#include "duckdb/function/aggregate_state_layout.hpp" #include "duckdb/function/function_set.hpp" namespace duckdb { @@ -11,11 +12,10 @@ namespace duckdb { namespace { struct ProductState { - static constexpr const char *STATE_NAMES[] = {"empty", "val"}; - using STATE_TYPE = StructStateType; + using STATE_TYPE = OptionalStateType; - bool empty; double val; + bool is_set; }; struct ProductReduce { diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/mad.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/mad.cpp index 098f64330..d25802751 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/mad.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/mad.cpp @@ -174,7 +174,7 @@ template struct MedianAbsoluteDeviationOperation : QuantileOperation { template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (state.v.empty()) { + if (state.linked_list.total_capacity == 0) { finalize_data.ReturnNull(); return; } @@ -183,11 +183,12 @@ struct MedianAbsoluteDeviationOperation : QuantileOperation { auto &bind_data = finalize_data.input.bind_data->Cast(); D_ASSERT(bind_data.quantiles.size() == 1); const auto &q = bind_data.quantiles[0]; - QuantileInterpolator interp(q, state.v.size(), false); - const auto med = interp.template Operation(state.v.data(), finalize_data.result); + auto &flattened = FlattenedQuantileValues::Flatten(finalize_data, state.linked_list); + QuantileInterpolator interp(q, state.linked_list.total_capacity, false); + const auto med = interp.template Operation(flattened.Data(), finalize_data.result); MadAccessor accessor(med); - target = interp.template Operation(state.v.data(), finalize_data.result, accessor); + target = interp.template Operation(flattened.Data(), finalize_data.result, accessor); } template @@ -269,10 +270,9 @@ unique_ptr BindMAD(BindAggregateFunctionInput &input) { template AggregateFunction GetTypedMedianAbsoluteDeviationAggregateFunction(const LogicalType &input_type, const LogicalType &target_type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = MedianAbsoluteDeviationOperation; - auto fun = AggregateFunction::UnaryAggregateDestructor(input_type, target_type); + auto fun = QuantileBufferingAggregate(input_type, target_type); fun.SetBindCallback(BindMAD); fun.SetOrderDependent(AggregateOrderDependent::NOT_ORDER_DEPENDENT); #ifndef DUCKDB_SMALLER_BINARY diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp index 147ce9a11..0a8de1852 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp @@ -11,7 +11,8 @@ #include "duckdb/common/types/timestamp.hpp" #include "duckdb/common/serializer/serializer.hpp" #include "duckdb/common/serializer/deserializer.hpp" -#include "duckdb/function/aggregate/sort_key_helpers.hpp" +#include "duckdb/function/aggregate/list_aggregate.hpp" +#include "duckdb/function/create_sort_key.hpp" namespace duckdb { @@ -155,19 +156,20 @@ string_t QuantileCast::Operation(const string_t &src, Vector &result) { //===--------------------------------------------------------------------===// // Scalar Quantile //===--------------------------------------------------------------------===// -template +template struct QuantileScalarOperation : public QuantileOperation { template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (state.v.empty()) { + if (state.linked_list.total_capacity == 0) { finalize_data.ReturnNull(); return; } D_ASSERT(finalize_data.input.bind_data); auto &bind_data = finalize_data.input.bind_data->Cast(); D_ASSERT(bind_data.quantiles.size() == 1); - QuantileInterpolator interp(bind_data.quantiles[0], state.v.size(), bind_data.desc); - target = interp.template Operation(state.v.data(), finalize_data.result); + auto &flattened = FlattenedQuantileValues::Flatten(finalize_data, state.linked_list); + QuantileInterpolator interp(bind_data.quantiles[0], state.linked_list.total_capacity, bind_data.desc); + target = interp.template Operation(flattened.Data(), finalize_data.result); } template @@ -226,23 +228,34 @@ struct QuantileScalarOperation : public QuantileOperation { } }; +//! Buffers the sort key of each input row in the state's linked list - NULL inputs are skipped +static void QuantileSortKeyUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &states, idx_t count) { + D_ASSERT(input_count == 1); + Vector sort_keys(LogicalType::BLOB); + const OrderModifiers modifiers(OrderType::ASCENDING, OrderByNullType::NULLS_LAST); + CreateSortKeyHelpers::CreateSortKeyWithValidity(inputs[0], sort_keys, modifiers, count); + ListUpdateFunction(&sort_keys, aggr_input_data, 1, states, count); +} + struct QuantileScalarFallback : QuantileOperation { - template - static void Execute(STATE &state, const INPUT_TYPE &key, AggregateInputData &input_data) { - state.AddElement(key, input_data); + //! The fallback buffers sort keys instead of the input values + static LogicalType GetElementType(AggregateInputData &) { + return LogicalType::BLOB; } template static void Finalize(STATE &state, AggregateFinalizeData &finalize_data) { - if (state.v.empty()) { + if (state.linked_list.total_capacity == 0) { finalize_data.ReturnNull(); return; } D_ASSERT(finalize_data.input.bind_data); auto &bind_data = finalize_data.input.bind_data->Cast(); D_ASSERT(bind_data.quantiles.size() == 1); - QuantileInterpolator interp(bind_data.quantiles[0], state.v.size(), bind_data.desc); - auto interpolation_result = interp.InterpolateInternal(state.v.data()); + auto &flattened = FlattenedQuantileValues::Flatten(finalize_data, state.linked_list); + QuantileInterpolator interp(bind_data.quantiles[0], state.linked_list.total_capacity, bind_data.desc); + auto interpolation_result = interp.InterpolateInternal(flattened.Data()); CreateSortKeyHelpers::DecodeSortKey(interpolation_result, finalize_data.result, finalize_data.result_idx, OrderModifiers(OrderType::ASCENDING, OrderByNullType::NULLS_LAST)); } @@ -255,7 +268,7 @@ template struct QuantileListOperation : QuantileOperation { template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (state.v.empty()) { + if (state.linked_list.total_capacity == 0) { finalize_data.ReturnNull(); return; } @@ -268,7 +281,8 @@ struct QuantileListOperation : QuantileOperation { ListVector::Reserve(finalize_data.result, ridx + bind_data.quantiles.size()); auto rdata = FlatVector::GetDataMutable(result); - auto v_t = state.v.data(); + auto &flattened = FlattenedQuantileValues::Flatten(finalize_data, state.linked_list); + auto v_t = flattened.Data(); D_ASSERT(v_t); auto &entry = target; @@ -276,7 +290,7 @@ struct QuantileListOperation : QuantileOperation { idx_t lower = 0; for (const auto &q : bind_data.order) { const auto &quantile = bind_data.quantiles[q]; - QuantileInterpolator interp(quantile, state.v.size(), bind_data.desc); + QuantileInterpolator interp(quantile, state.linked_list.total_capacity, bind_data.desc); interp.begin = lower; rdata[ridx + q] = interp.template Operation(v_t, result); lower = interp.FRN; @@ -335,14 +349,14 @@ struct QuantileListOperation : QuantileOperation { }; struct QuantileListFallback : QuantileOperation { - template - static void Execute(STATE &state, const INPUT_TYPE &key, AggregateInputData &input_data) { - state.AddElement(key, input_data); + //! The fallback buffers sort keys instead of the input values + static LogicalType GetElementType(AggregateInputData &) { + return LogicalType::BLOB; } template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (state.v.empty()) { + if (state.linked_list.total_capacity == 0) { finalize_data.ReturnNull(); return; } @@ -354,16 +368,16 @@ struct QuantileListFallback : QuantileOperation { auto ridx = ListVector::GetListSize(finalize_data.result); ListVector::Reserve(finalize_data.result, ridx + bind_data.quantiles.size()); - D_ASSERT(state.v.data()); + auto &flattened = FlattenedQuantileValues::Flatten(finalize_data, state.linked_list); auto &entry = target; entry.offset = ridx; idx_t lower = 0; for (const auto &q : bind_data.order) { const auto &quantile = bind_data.quantiles[q]; - QuantileInterpolator interp(quantile, state.v.size(), bind_data.desc); + QuantileInterpolator interp(quantile, state.linked_list.total_capacity, bind_data.desc); interp.begin = lower; - auto interpolation_result = interp.InterpolateInternal(state.v.data()); + auto interpolation_result = interp.InterpolateInternal(flattened.Data()); CreateSortKeyHelpers::DecodeSortKey(interpolation_result, result, ridx + q, OrderModifiers(OrderType::ASCENDING, OrderByNullType::NULLS_LAST)); lower = interp.FRN; @@ -398,7 +412,7 @@ AggregateFunction GetDiscreteQuantileTemplated(const LogicalType &type) { case PhysicalType::INTERVAL: return OP::template GetFunction(type); case PhysicalType::VARCHAR: - return OP::template GetFunction(type); + return OP::template GetFunction(type); #endif default: return OP::GetFallback(type); @@ -406,12 +420,11 @@ AggregateFunction GetDiscreteQuantileTemplated(const LogicalType &type) { } struct ScalarDiscreteQuantile { - template + template static AggregateFunction GetFunction(const LogicalType &type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileScalarOperation; - auto fun = AggregateFunction::UnaryAggregateDestructor(type, type); + auto fun = QuantileBufferingAggregate(type, type); #ifndef DUCKDB_SMALLER_BINARY fun.SetWindowBatchCallback(OP::Window); fun.SetWindowInitCallback(OP::WindowInit); @@ -420,36 +433,24 @@ struct ScalarDiscreteQuantile { } static AggregateFunction GetFallback(const LogicalType &type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileScalarFallback; AggregateFunction fun({type}, type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, - AggregateSortKeyHelpers::UnaryUpdate, - AggregateFunction::StateCombine, + QuantileSortKeyUpdate, ListCombineFunction, AggregateFunction::StateVoidFinalize, nullptr, nullptr, AggregateFunction::StateDestroy); return fun; } }; -template -static AggregateFunction QuantileListAggregate(const LogicalType &input_type, const LogicalType &child_type) { // NOLINT - LogicalType result_type = LogicalType::LIST(child_type); - return AggregateFunction( - {input_type}, result_type, AggregateFunction::StateSize, - AggregateFunction::StateInitialize, - AggregateFunction::UnaryScatterUpdate, AggregateFunction::StateCombine, - AggregateFunction::StateFinalize, FunctionNullHandling::DEFAULT_NULL_HANDLING, - AggregateFunction::NoClusterUpdate(), AggregateFunction::NoBind(), AggregateFunction::StateDestroy); -} - struct ListDiscreteQuantile { - template + template static AggregateFunction GetFunction(const LogicalType &type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileListOperation; - auto fun = QuantileListAggregate(type, type); + auto fun = QuantileBufferingAggregate(type, LogicalType::LIST(type)); fun.SetOrderDependent(AggregateOrderDependent::NOT_ORDER_DEPENDENT); #ifndef DUCKDB_SMALLER_BINARY fun.SetWindowBatchCallback(OP::template Window); @@ -459,13 +460,12 @@ struct ListDiscreteQuantile { } static AggregateFunction GetFallback(const LogicalType &type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileListFallback; AggregateFunction fun({type}, LogicalType::LIST(type), AggregateFunction::StateSize, AggregateFunction::StateInitialize, - AggregateSortKeyHelpers::UnaryUpdate, - AggregateFunction::StateCombine, + QuantileSortKeyUpdate, ListCombineFunction, AggregateFunction::StateFinalize, nullptr, nullptr, AggregateFunction::StateDestroy); return fun; @@ -539,11 +539,9 @@ AggregateFunction GetContinuousQuantileTemplated(const LogicalType &type) { struct ScalarContinuousQuantile { template static AggregateFunction GetFunction(const LogicalType &input_type, const LogicalType &target_type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileScalarOperation; - auto fun = - AggregateFunction::UnaryAggregateDestructor(input_type, target_type); + auto fun = QuantileBufferingAggregate(input_type, target_type); fun.SetOrderDependent(AggregateOrderDependent::NOT_ORDER_DEPENDENT); #ifndef DUCKDB_SMALLER_BINARY fun.SetWindowBatchCallback(OP::template Window); @@ -556,9 +554,9 @@ struct ScalarContinuousQuantile { struct ListContinuousQuantile { template static AggregateFunction GetFunction(const LogicalType &input_type, const LogicalType &target_type) { - using STATE = QuantileState; + using STATE = QuantileState; using OP = QuantileListOperation; - auto fun = QuantileListAggregate(input_type, target_type); + auto fun = QuantileBufferingAggregate(input_type, LogicalType::LIST(target_type)); fun.SetOrderDependent(AggregateOrderDependent::NOT_ORDER_DEPENDENT); #ifndef DUCKDB_SMALLER_BINARY fun.SetWindowBatchCallback(OP::template Window); diff --git a/src/duckdb/extension/core_functions/aggregate/nested/list.cpp b/src/duckdb/extension/core_functions/aggregate/nested/list.cpp index f56481c01..7d3bc0012 100644 --- a/src/duckdb/extension/core_functions/aggregate/nested/list.cpp +++ b/src/duckdb/extension/core_functions/aggregate/nested/list.cpp @@ -1,181 +1,35 @@ -#include "duckdb/common/vector/flat_vector.hpp" -#include "duckdb/common/vector/list_vector.hpp" -#include "duckdb/common/pair.hpp" -#include "duckdb/common/types/list_segment.hpp" +#include "duckdb/function/aggregate/list_aggregate.hpp" #include "core_functions/aggregate/nested_functions.hpp" -#include "duckdb/planner/expression/bound_aggregate_expression.hpp" namespace duckdb { namespace { -struct ListBindData : public FunctionData { - explicit ListBindData(const LogicalType &stype_p); - - LogicalType stype; - ListSegmentFunctions functions; - - unique_ptr Copy() const override { - return make_uniq(stype); - } - - bool Equals(const FunctionData &other_p) const override { - auto &other = other_p.Cast(); - return stype == other.stype; - } -}; - -ListBindData::ListBindData(const LogicalType &stype_p) : stype(stype_p) { - // always unnest once because the result vector is of type LIST - auto type = ListType::GetChildType(stype_p); - GetSegmentDataFunctions(functions, type); -} - -struct ListAggState { - LinkedList linked_list; -}; - -struct ListFunction { - static bool IgnoreNull() { - return false; - } -}; - -void ListUpdateFunction(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, Vector &state_vector, - idx_t count) { - D_ASSERT(input_count == 1); - auto &input = inputs[0]; - RecursiveUnifiedVectorFormat input_data; - Vector::RecursiveToUnifiedFormat(input, input_data); - - auto states = state_vector.Values(); - auto &list_bind_data = aggr_input_data.bind_data->Cast(); - - for (idx_t i = 0; i < count; i++) { - auto &state = *states[i].GetValue(); - aggr_input_data.allocator.AlignNext(); - list_bind_data.functions.AppendRow(aggr_input_data.allocator, state.linked_list, input_data, i); - } -} - -void ListAbsorbFunction(Vector &states_vector, Vector &combined, AggregateInputData &aggr_input_data, idx_t count) { - D_ASSERT(aggr_input_data.combine_type == AggregateCombineType::ALLOW_DESTRUCTIVE); - - auto states = states_vector.Values(); - auto combined_ptr = FlatVector::GetDataMutable(combined); - for (idx_t i = 0; i < count; i++) { - auto &state = *states[i].GetValue(); - if (state.linked_list.total_capacity == 0) { - // NULL, no need to append - // this can happen when adding a FILTER to the grouping, e.g., - // LIST(i) FILTER (WHERE i <> 3) - continue; - } - - if (combined_ptr[i]->linked_list.total_capacity == 0) { - combined_ptr[i]->linked_list = state.linked_list; - continue; - } - - // append the linked list - combined_ptr[i]->linked_list.last_segment->next = state.linked_list.first_segment; - combined_ptr[i]->linked_list.last_segment = state.linked_list.last_segment; - combined_ptr[i]->linked_list.total_capacity += state.linked_list.total_capacity; - } -} - void ListFinalize(Vector &states_vector, AggregateInputData &aggr_input_data, Vector &result, idx_t count, idx_t offset) { auto states = states_vector.Values(); D_ASSERT(result.GetType().id() == LogicalTypeId::LIST); - auto &mask = FlatVector::ValidityMutable(result); - auto result_data = FlatVector::ScatterWriter(result); - size_t total_len = ListVector::GetListSize(result); - - auto &list_bind_data = aggr_input_data.bind_data->Cast(); - - // first iterate over all entries and set up the list entries, and get the newly required total length - for (idx_t i = 0; i < count; i++) { - auto &state = *states[i].GetValue(); - const auto rid = i + offset; - result_data[rid].offset = total_len; - if (state.linked_list.total_capacity == 0) { - mask.SetInvalid(rid); - result_data[rid].length = 0; - continue; - } - - // set the length and offset of this list in the result vector - auto total_capacity = state.linked_list.total_capacity; - result_data[rid].length = total_capacity; - total_len += total_capacity; - } - - // reserve capacity, then iterate over all entries again and copy over the data to the child vector - ListVector::Reserve(result, total_len); - auto &result_child = ListVector::GetChildMutable(result); - for (idx_t i = 0; i < count; i++) { - auto &state = *states[i].GetValue(); - const auto rid = i + offset; - if (state.linked_list.total_capacity == 0) { - continue; - } - - idx_t current_offset = result_data[rid].offset; - list_bind_data.functions.BuildListVector(state.linked_list, result_child, current_offset); - } - - ListVector::SetListSize(result, total_len); - FlatVector::SetSize(result, count_t(offset + count)); -} - -void ListCombineFunction(Vector &states_vector, Vector &combined, AggregateInputData &aggr_input_data, idx_t count) { - // Can we use destructive combining? - if (aggr_input_data.combine_type == AggregateCombineType::ALLOW_DESTRUCTIVE) { - ListAbsorbFunction(states_vector, combined, aggr_input_data, count); - return; - } - - auto states = states_vector.Values(); - auto combined_ptr = FlatVector::GetDataMutable(combined); - - auto &list_bind_data = aggr_input_data.bind_data->Cast(); - auto result_type = ListType::GetChildType(list_bind_data.stype); + ListSegmentFunctions functions; + GetSegmentDataFunctions(functions, ListType::GetChildType(result.GetType())); + vector linked_lists; + linked_lists.reserve(count); for (idx_t i = 0; i < count; i++) { - auto &source = *states[i].GetValue(); - auto &target = *combined_ptr[i]; - - const auto entry_count = source.linked_list.total_capacity; - Vector input(result_type, source.linked_list.total_capacity); - list_bind_data.functions.BuildListVector(source.linked_list, input, 0); - - RecursiveUnifiedVectorFormat input_data; - Vector::RecursiveToUnifiedFormat(input, input_data); - - for (idx_t entry_idx = 0; entry_idx < entry_count; ++entry_idx) { - aggr_input_data.allocator.AlignNext(); - list_bind_data.functions.AppendRow(aggr_input_data.allocator, target.linked_list, input_data, entry_idx); - } + linked_lists.push_back(states[i].GetValue()->linked_list); } -} - -unique_ptr ListBindFunction(BindAggregateFunctionInput &input) { - auto &function = input.GetBoundFunction(); - auto &arguments = input.GetArguments(); - function.SetReturnType(LogicalType::LIST(arguments[0]->GetReturnType())); - return make_uniq(function.GetReturnType()); + functions.BuildLists(linked_lists, result, offset); } } // namespace AggregateFunction ListFun::GetFunction() { - auto func = AggregateFunction( - {LogicalType::TEMPLATE("T")}, LogicalType::LIST(LogicalType::TEMPLATE("T")), - AggregateFunction::StateSize, AggregateFunction::StateInitialize, - ListUpdateFunction, ListCombineFunction, ListFinalize, nullptr, ListBindFunction, nullptr, nullptr, nullptr); + auto func = AggregateFunction({LogicalType::TEMPLATE("T")}, LogicalType::LIST(LogicalType::TEMPLATE("T")), + AggregateFunction::StateSize, + AggregateFunction::StateInitialize, ListUpdateFunction<>, + ListCombineFunction, ListFinalize, nullptr, nullptr, nullptr, nullptr); + AggregateFunction::WireStructStateType(func); return func; } diff --git a/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_state.hpp b/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_state.hpp index 48c846632..312e00ab3 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_state.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_state.hpp @@ -9,35 +9,65 @@ #pragma once #include "core_functions/aggregate/quantile_sort_tree.hpp" +#include "duckdb/common/types/data_chunk.hpp" +#include "duckdb/common/types/list_segment.hpp" +#include "duckdb/function/aggregate/list_aggregate.hpp" #include "SkipList.h" namespace duckdb { -struct QuantileOperation { - template - static void Initialize(STATE &state) { - new (&state) STATE(); +//! Flattens the values of a linked list into a contiguous array for interpolation. +//! The flattened values are mutable - the interpolators partially sort them in place. +//! The flattened chunk is cached in the finalize data's local state, so that it is allocated (at most) once per +//! result chunk instead of once per finalized group. +template +struct FlattenedQuantileValues : FunctionLocalState { + FlattenedQuantileValues(const LogicalType &type, idx_t capacity_p) : capacity(capacity_p) { + chunk.Initialize(Allocator::DefaultAllocator(), {type}, capacity_p); } - template - static void ConstantOperation(STATE &state, const INPUT_TYPE &input, AggregateUnaryInput &unary_input, - idx_t count) { - for (idx_t i = 0; i < count; i++) { - Operation(state, input, unary_input); + //! Flatten the values of the given linked list into the chunk cached in the finalize data + static FlattenedQuantileValues &Flatten(AggregateFinalizeData &finalize_data, const LinkedList &linked_list) { + const auto type = PrimitiveToLogicalType(); + const auto required_capacity = MaxValue(linked_list.total_capacity, 1); + if (!finalize_data.local_state) { + finalize_data.local_state = make_uniq(type, NextPowerOfTwo(required_capacity)); } + auto &values = finalize_data.local_state->Cast(); + if (values.capacity < required_capacity) { + // grow the cached chunk + values.capacity = NextPowerOfTwo(required_capacity); + values.chunk.Destroy(); + values.chunk.Initialize(Allocator::DefaultAllocator(), {type}, values.capacity); + } else { + // re-use the allocated chunk - resetting clears the string heap of the previously flattened state + values.chunk.Reset(); + } + ListSegmentFunctions functions; + GetSegmentDataFunctions(functions, type); + functions.BuildListVector(linked_list, values.chunk.data[0], 0); + return values; } - template - static void Operation(STATE &state, const INPUT_TYPE &input, AggregateUnaryInput &aggr_input) { - state.AddElement(input, aggr_input.input); + INPUT_TYPE *Data() { + return FlatVector::GetDataMutable(chunk.data[0]); } - template - static void Combine(const STATE &source, STATE &target, AggregateInputData &) { - if (source.v.empty()) { - return; - } - target.v.insert(target.v.end(), source.v.begin(), source.v.end()); + //! The flattened values (a single-column chunk) - strings are materialized into the chunk's string heap + DataChunk chunk; + //! The allocated capacity of the chunk + idx_t capacity; +}; + +struct QuantileOperation { + template + static void Initialize(STATE &state) { + new (&state) STATE(); + } + + //! The type of the values buffered in the linked list - used by the shared list update/combine functions + static LogicalType GetElementType(AggregateInputData &aggr_input_data) { + return aggr_input_data.function.GetArguments()[0]; } template @@ -45,10 +75,6 @@ struct QuantileOperation { state.~STATE(); } - static bool IgnoreNull() { - return true; - } - template static void WindowInit(AggregateInputData &aggr_input_data, const WindowPartitionInput &partition, data_ptr_t g_state) { @@ -94,6 +120,19 @@ struct QuantileOperation { } }; +//! Creates a quantile aggregate that buffers the input values in a linked list, sharing the "list" aggregate +//! callbacks for update/combine - the operation only provides the finalizer. +//! Quantiles ignore NULL values, so they are filtered out while appending. +template +AggregateFunction QuantileBufferingAggregate(const LogicalType &input_type, const LogicalType &result_type) { + return AggregateFunction({input_type}, result_type, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, + ListUpdateFunction, ListCombineFunction, + AggregateFunction::StateFinalize, + FunctionNullHandling::DEFAULT_NULL_HANDLING, AggregateFunction::NoClusterUpdate(), + AggregateFunction::NoBind(), AggregateFunction::StateDestroy); +} + template struct SkipLess { inline bool operator()(const T &lhi, const T &rhi) const { @@ -242,41 +281,17 @@ struct WindowQuantileState { } }; -struct QuantileStandardType { - template - static T Operation(T input, AggregateInputData &) { - return input; - } -}; - -struct QuantileStringType { - template - static T Operation(T input, AggregateInputData &input_data) { - if (input.IsInlined()) { - return input; - } - auto string_data = input_data.allocator.Allocate(input.GetSize()); - memcpy(string_data, input.GetData(), input.GetSize()); - return string_t(char_ptr_cast(string_data), UnsafeNumericCast(input.GetSize())); - } -}; - -template -struct QuantileState { +//! Regular aggregation buffers the values in the linked list of the ListAggState base, +//! shared with the "list" aggregate callbacks +template +struct QuantileState : ListAggState { using InputType = INPUT_TYPE; using CursorType = QuantileCursor; - // Regular aggregation - vector v; - - // Window Quantile State + // Window Quantile State (only used for window execution) unique_ptr> window_state; unique_ptr window_cursor; - void AddElement(INPUT_TYPE element, AggregateInputData &aggr_input) { - v.emplace_back(TYPE_OP::Operation(element, aggr_input)); - } - bool HasTree() const { return window_state && window_state->HasTree(); } diff --git a/src/duckdb/extension/parquet/parquet_writer.cpp b/src/duckdb/extension/parquet/parquet_writer.cpp index 535d1d050..7bc7e8fd0 100644 --- a/src/duckdb/extension/parquet/parquet_writer.cpp +++ b/src/duckdb/extension/parquet/parquet_writer.cpp @@ -1306,6 +1306,7 @@ void ParquetWriter::Finalize() { GatherWrittenStatistics(); written_stats->file_size_bytes = writer->GetTotalWritten(); written_stats->footer_size_bytes = Value::UBIGINT(footer_size); + written_stats->extra_info["row_group_count"] = Value::UBIGINT(NumberOfRowGroups()); } // flush to disk diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp index 187894805..fabd9dccc 100644 --- a/src/duckdb/src/common/enum_util.cpp +++ b/src/duckdb/src/common/enum_util.cpp @@ -34,7 +34,6 @@ #include "duckdb/common/enums/debug_verification_mode.hpp" #include "duckdb/common/enums/deprecated_using_key_syntax.hpp" #include "duckdb/common/enums/destroy_buffer_upon.hpp" -#include "duckdb/common/enums/explain_format.hpp" #include "duckdb/common/enums/expression_type.hpp" #include "duckdb/common/enums/file_compression_type.hpp" #include "duckdb/common/enums/file_glob_options.hpp" @@ -60,7 +59,6 @@ #include "duckdb/common/enums/physical_operator_type.hpp" #include "duckdb/common/enums/prepared_statement_mode.hpp" #include "duckdb/common/enums/preserve_order.hpp" -#include "duckdb/common/enums/profiler_format.hpp" #include "duckdb/common/enums/quantile_enum.hpp" #include "duckdb/common/enums/relation_type.hpp" #include "duckdb/common/enums/row_group_append_mode.hpp" @@ -149,7 +147,7 @@ #include "duckdb/main/extension.hpp" #include "duckdb/main/extension_helper.hpp" #include "duckdb/main/extension_install_info.hpp" -#include "duckdb/main/gathered_metrics.hpp" +#include "duckdb/main/profiler/gathered_metrics.hpp" #include "duckdb/main/query_parameters.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/main/query_result.hpp" @@ -185,6 +183,7 @@ #include "duckdb/parser/peg/matcher.hpp" #include "duckdb/parser/peg/sql_formatter.hpp" #include "duckdb/parser/peg/transformer/parse_result.hpp" +#include "duckdb/parser/peg/transformer/peg_transformer.hpp" #include "duckdb/parser/query_node.hpp" #include "duckdb/parser/result_modifier.hpp" #include "duckdb/parser/simplified_token.hpp" @@ -1911,29 +1910,6 @@ ExceptionType EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetExceptionTypeValues(), 43, "ExceptionType", value)); } -const StringUtil::EnumStringLiteral *GetExplainFormatValues() { - static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(ExplainFormat::DEFAULT), "DEFAULT" }, - { static_cast(ExplainFormat::TEXT), "TEXT" }, - { static_cast(ExplainFormat::JSON), "JSON" }, - { static_cast(ExplainFormat::HTML), "HTML" }, - { static_cast(ExplainFormat::GRAPHVIZ), "GRAPHVIZ" }, - { static_cast(ExplainFormat::YAML), "YAML" }, - { static_cast(ExplainFormat::MERMAID), "MERMAID" } - }; - return values; -} - -template<> -const char* EnumUtil::ToChars(ExplainFormat value) { - return StringUtil::EnumToString(GetExplainFormatValues(), 7, "ExplainFormat", static_cast(value)); -} - -template<> -ExplainFormat EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetExplainFormatValues(), 7, "ExplainFormat", value)); -} - const StringUtil::EnumStringLiteral *GetExplainOutputTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(ExplainOutputType::ALL), "ALL" }, @@ -2623,6 +2599,27 @@ GeometryType EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetGeometryTypeValues(), 8, "GeometryType", value)); } +const StringUtil::EnumStringLiteral *GetGroupByExpressionInfoTypeValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(GroupByExpressionInfoType::EXPRESSION), "EXPRESSION" }, + { static_cast(GroupByExpressionInfoType::EMPTY), "EMPTY" }, + { static_cast(GroupByExpressionInfoType::CUBE), "CUBE" }, + { static_cast(GroupByExpressionInfoType::ROLLUP), "ROLLUP" }, + { static_cast(GroupByExpressionInfoType::GROUPING_SETS), "GROUPING_SETS" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(GroupByExpressionInfoType value) { + return StringUtil::EnumToString(GetGroupByExpressionInfoTypeValues(), 5, "GroupByExpressionInfoType", static_cast(value)); +} + +template<> +GroupByExpressionInfoType EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetGroupByExpressionInfoTypeValues(), 5, "GroupByExpressionInfoType", value)); +} + const StringUtil::EnumStringLiteral *GetHLLStorageTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(HLLStorageType::HLL_V1), "HLL_V1" }, @@ -4232,29 +4229,6 @@ PreserveOrderType EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetPreserveOrderTypeValues(), 3, "PreserveOrderType", value)); } -const StringUtil::EnumStringLiteral *GetProfilerPrintFormatValues() { - static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(ProfilerPrintFormat::QUERY_TREE), "QUERY_TREE" }, - { static_cast(ProfilerPrintFormat::JSON), "JSON" }, - { static_cast(ProfilerPrintFormat::QUERY_TREE_OPTIMIZER), "QUERY_TREE_OPTIMIZER" }, - { static_cast(ProfilerPrintFormat::NO_OUTPUT), "NO_OUTPUT" }, - { static_cast(ProfilerPrintFormat::HTML), "HTML" }, - { static_cast(ProfilerPrintFormat::GRAPHVIZ), "GRAPHVIZ" }, - { static_cast(ProfilerPrintFormat::MERMAID), "MERMAID" } - }; - return values; -} - -template<> -const char* EnumUtil::ToChars(ProfilerPrintFormat value) { - return StringUtil::EnumToString(GetProfilerPrintFormatValues(), 7, "ProfilerPrintFormat", static_cast(value)); -} - -template<> -ProfilerPrintFormat EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetProfilerPrintFormatValues(), 7, "ProfilerPrintFormat", value)); -} - const StringUtil::EnumStringLiteral *GetProfilingCoverageValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(ProfilingCoverage::SELECT), "SELECT" }, diff --git a/src/duckdb/src/common/extra_type_info.cpp b/src/duckdb/src/common/extra_type_info.cpp index 74ebe5fb1..cd3ae1bd2 100644 --- a/src/duckdb/src/common/extra_type_info.cpp +++ b/src/duckdb/src/common/extra_type_info.cpp @@ -109,6 +109,13 @@ shared_ptr ExtraTypeInfo::DeepCopy() const { return Copy(); } +void ExtraTypeInfo::CopyBaseInfo(ExtraTypeInfo &target) const { + target.alias = alias; + if (extension_info) { + target.extension_info = make_uniq(*extension_info); + } +} + bool ExtraTypeInfo::Equals(ExtraTypeInfo *other_p) const { if (type == ExtraTypeInfoType::INVALID_TYPE_INFO || type == ExtraTypeInfoType::STRING_TYPE_INFO || type == ExtraTypeInfoType::GENERIC_TYPE_INFO) { @@ -209,7 +216,9 @@ shared_ptr ListTypeInfo::Copy() const { } shared_ptr ListTypeInfo::DeepCopy() const { - return make_shared_ptr(child_type.DeepCopy()); + auto result = make_shared_ptr(child_type.DeepCopy()); + CopyBaseInfo(*result); + return result; } //===--------------------------------------------------------------------===// @@ -240,7 +249,9 @@ shared_ptr StructTypeInfo::DeepCopy() const { for (const auto &child_type : child_types) { copied_child_types.emplace_back(child_type.first, child_type.second.DeepCopy()); } - return make_shared_ptr(std::move(copied_child_types)); + auto result = make_shared_ptr(type, std::move(copied_child_types)); + CopyBaseInfo(*result); + return result; } //===--------------------------------------------------------------------===// @@ -357,25 +368,22 @@ const idx_t &EnumTypeInfo::GetDictSize() const { return dict_size; } -LogicalType EnumTypeInfo::CreateType(const Vector &ordered_data, idx_t size) { - // Generate EnumTypeInfo - shared_ptr info; +shared_ptr EnumTypeInfo::CreateTypeInfo(const Vector &ordered_data, idx_t size) { auto enum_internal_type = EnumTypeInfo::DictType(size); switch (enum_internal_type) { case PhysicalType::UINT8: - info = make_shared_ptr>(ordered_data, size); - break; + return make_shared_ptr>(ordered_data, size); case PhysicalType::UINT16: - info = make_shared_ptr>(ordered_data, size); - break; + return make_shared_ptr>(ordered_data, size); case PhysicalType::UINT32: - info = make_shared_ptr>(ordered_data, size); - break; + return make_shared_ptr>(ordered_data, size); default: throw InternalException("Invalid Physical Type for ENUMs"); } - // Generate Actual Enum Type - return LogicalType(LogicalTypeId::ENUM, info); +} + +LogicalType EnumTypeInfo::CreateType(const Vector &ordered_data, idx_t size) { + return LogicalType(LogicalTypeId::ENUM, CreateTypeInfo(ordered_data, size)); } template @@ -455,8 +463,10 @@ void EnumTypeInfo::Serialize(Serializer &serializer) const { } shared_ptr EnumTypeInfo::Copy() const { - Vector values_insert_order_copy(Vector::Ref(values_insert_order)); - return make_shared_ptr(values_insert_order_copy, dict_size); + // create a templated copy so that the value lookup map is rebuilt - the dictionary itself is shared + auto result = CreateTypeInfo(values_insert_order, dict_size); + CopyBaseInfo(*result); + return result; } //===--------------------------------------------------------------------===// @@ -477,7 +487,9 @@ shared_ptr ArrayTypeInfo::Copy() const { } shared_ptr ArrayTypeInfo::DeepCopy() const { - return make_shared_ptr(child_type.DeepCopy(), size); + auto result = make_shared_ptr(child_type.DeepCopy(), size); + CopyBaseInfo(*result); + return result; } //===--------------------------------------------------------------------===// @@ -500,7 +512,9 @@ shared_ptr AnyTypeInfo::Copy() const { } shared_ptr AnyTypeInfo::DeepCopy() const { - return make_shared_ptr(target_type.DeepCopy(), cast_score); + auto result = make_shared_ptr(target_type.DeepCopy(), cast_score); + CopyBaseInfo(*result); + return result; } //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/common/tree_renderer.cpp b/src/duckdb/src/common/tree_renderer.cpp index c7a810468..4b9f5c927 100644 --- a/src/duckdb/src/common/tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer.cpp @@ -5,29 +5,85 @@ #include "duckdb/common/tree_renderer/graphviz_tree_renderer.hpp" #include "duckdb/common/tree_renderer/yaml_tree_renderer.hpp" #include "duckdb/common/tree_renderer/mermaid_tree_renderer.hpp" - -#include +#include "duckdb/main/profiler/profiler_print_format.hpp" +#include "duckdb/common/exception.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/main/query_profiler.hpp" namespace duckdb { -unique_ptr TreeRenderer::CreateRenderer(ExplainFormat format) { - switch (format) { - case ExplainFormat::DEFAULT: - case ExplainFormat::TEXT: - return make_uniq(); - case ExplainFormat::JSON: - return make_uniq(); - case ExplainFormat::HTML: - return make_uniq(); - case ExplainFormat::GRAPHVIZ: - return make_uniq(); - case ExplainFormat::YAML: - return make_uniq(); - case ExplainFormat::MERMAID: - return make_uniq(); - default: - throw NotImplementedException("ExplainFormat %s not implemented", EnumUtil::ToString(format)); +//===--------------------------------------------------------------------===// +// Profiler output (base implementations) +//===--------------------------------------------------------------------===// +string TreeRenderer::RenderProfiler(const QueryProfiler &profiler) { + // by default, render the profiling node tree using this renderer (covers HTML/GraphViz/Mermaid) + return profiler.RenderProfilingNodeTree(*this); +} + +string TreeRenderer::RenderProfilerDisabled() { + return "Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling!"; +} + +//===--------------------------------------------------------------------===// +// Built-in print format registry +//===--------------------------------------------------------------------===// +template +static unique_ptr MakeRenderer() { + return make_uniq(); +} + +static unique_ptr MakeNoOutputRenderer() { + // the "no_output" format renders nothing and so has no renderer + return nullptr; +} + +struct ProfilerPrintFormatEntry { + const char *name; + unique_ptr (*create_renderer)(); +}; + +static const ProfilerPrintFormatEntry PRINT_FORMATS[] = { + {"default", MakeRenderer}, + {"text", MakeRenderer}, + // aliases of "text" used by the profiler (e.g. PRAGMA enable_profiling = 'query_tree') + {"query_tree", MakeRenderer}, + {"query_tree_optimizer", MakeRenderer}, + // format that renders no output at all + {"no_output", MakeNoOutputRenderer}, + {"json", MakeRenderer}, + {"html", MakeRenderer}, + {"graphviz", MakeRenderer}, + {"yaml", MakeRenderer}, + {"mermaid", MakeRenderer}, +}; + +//! Look up the registry entry for a format name, throwing InvalidInputException (listing valid names) when unknown. +static const ProfilerPrintFormatEntry &LookupProfilerPrintFormat(const string &name) { + auto lower = StringUtil::Lower(name); + for (auto &entry : PRINT_FORMATS) { + if (lower == entry.name) { + return entry; + } + } + vector options; + for (auto &entry : PRINT_FORMATS) { + options.push_back(entry.name); } + throw InvalidInputException("\"%s\" is not a valid FORMAT argument, valid options are: %s", name, + StringUtil::Join(options, ", ")); +} + +ProfilerPrintFormat ProfilerPrintFormat::FromString(const string &name) { + // return the canonical (lowercase) name for the matched entry + return ProfilerPrintFormat(LookupProfilerPrintFormat(name).name); +} + +unique_ptr TreeRenderer::CreateRenderer(const string &name) { + return LookupProfilerPrintFormat(name).create_renderer(); +} + +unique_ptr TreeRenderer::CreateRenderer(const ProfilerPrintFormat &format) { + return CreateRenderer(format.ToString()); } } // namespace duckdb diff --git a/src/duckdb/src/common/tree_renderer/graphviz_tree_renderer.cpp b/src/duckdb/src/common/tree_renderer/graphviz_tree_renderer.cpp index 146765bcf..6f36b1cfd 100644 --- a/src/duckdb/src/common/tree_renderer/graphviz_tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer/graphviz_tree_renderer.cpp @@ -105,4 +105,13 @@ digraph G { ss << result; } +string GRAPHVIZTreeRenderer::RenderProfilerDisabled() { + return R"( + digraph G { + node [shape=box, style=rounded, fontname="Courier New", fontsize=10]; + node_0_0 [label="Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling!"]; + } + )"; +} + } // namespace duckdb diff --git a/src/duckdb/src/common/tree_renderer/html_tree_renderer.cpp b/src/duckdb/src/common/tree_renderer/html_tree_renderer.cpp index c59705828..cc07f0039 100644 --- a/src/duckdb/src/common/tree_renderer/html_tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer/html_tree_renderer.cpp @@ -264,4 +264,13 @@ void HTMLTreeRenderer::ToStreamInternal(RenderTree &root, std::ostream &ss) { ss << result; } +string HTMLTreeRenderer::RenderProfilerDisabled() { + return R"( + + + Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling! + + )"; +} + } // namespace duckdb diff --git a/src/duckdb/src/common/tree_renderer/json_tree_renderer.cpp b/src/duckdb/src/common/tree_renderer/json_tree_renderer.cpp index 02551c3c5..067ab65a4 100644 --- a/src/duckdb/src/common/tree_renderer/json_tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer/json_tree_renderer.cpp @@ -1,6 +1,7 @@ #include "duckdb/common/tree_renderer/json_tree_renderer.hpp" #include "duckdb/common/pair.hpp" +#include "duckdb/main/query_profiler.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/execution/operator/aggregate/physical_hash_aggregate.hpp" #include "duckdb/execution/operator/join/physical_delim_join.hpp" @@ -113,4 +114,15 @@ void JSONTreeRenderer::ToStreamInternal(RenderTree &root, std::ostream &ss) { yyjson_mut_doc_free(doc); } +string JSONTreeRenderer::RenderProfiler(const QueryProfiler &profiler) { + // the JSON profiler output is the full query profile result tree (including query-level metrics) + return profiler.ToJSON(); +} + +string JSONTreeRenderer::RenderProfilerDisabled() { + return R"({ + "result": "disabled" +})"; +} + } // namespace duckdb diff --git a/src/duckdb/src/common/tree_renderer/mermaid_tree_renderer.cpp b/src/duckdb/src/common/tree_renderer/mermaid_tree_renderer.cpp index 9ff7b6539..3da70ac61 100644 --- a/src/duckdb/src/common/tree_renderer/mermaid_tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer/mermaid_tree_renderer.cpp @@ -130,4 +130,12 @@ void MermaidTreeRenderer::ToStreamInternal(RenderTree &root, std::ostream &ss) { } } +string MermaidTreeRenderer::RenderProfilerDisabled() { + return R"(flowchart TD + node_0_0["`**DISABLED** +Query profiling is disabled. +Use 'PRAGMA enable_profiling;' to enable profiling!`"] +)"; +} + } // namespace duckdb diff --git a/src/duckdb/src/common/tree_renderer/text_tree_renderer.cpp b/src/duckdb/src/common/tree_renderer/text_tree_renderer.cpp index 09dcb0356..504d71be9 100644 --- a/src/duckdb/src/common/tree_renderer/text_tree_renderer.cpp +++ b/src/duckdb/src/common/tree_renderer/text_tree_renderer.cpp @@ -1,6 +1,7 @@ #include "duckdb/common/tree_renderer/text_tree_renderer.hpp" #include "duckdb/common/pair.hpp" +#include "duckdb/main/query_profiler.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/execution/physical_operator.hpp" #include "duckdb/parallel/pipeline.hpp" @@ -26,6 +27,29 @@ struct StringSegment { } // namespace +static char GetSeparatorSetting(const string &name, const Value &value) { + auto separator = value.ToString(); + if (separator.size() != 1) { + throw InvalidInputException("Renderer setting \"%s\" must be a single character, got \"%s\"", name, separator); + } + return separator[0]; +} + +void TextTreeRenderer::Configure(const unordered_map &settings) { + for (auto &entry : settings) { + auto name = StringUtil::Lower(entry.first); + auto &value = entry.second; + if (name == "max_extra_lines") { + config.max_extra_lines = value.DefaultCastAs(LogicalType::UBIGINT).GetValue(); + } else if (name == "thousand_separator") { + config.thousand_separator = GetSeparatorSetting(name, value); + } else if (name == "decimal_separator") { + config.decimal_separator = GetSeparatorSetting(name, value); + } + // settings that are not recognized are ignored - they may be intended for a different renderer + } +} + void TextTreeRenderer::RenderTopLayer(RenderTree &root, std::ostream &ss, idx_t y) { for (idx_t x = 0; x < root.width; x++) { if (x * config.node_render_width >= config.maximum_render_width) { @@ -528,4 +552,9 @@ string TextTreeRenderer::ExtraInfoSeparator() { return StringUtil::Repeat(string(config.HORIZONTAL), (config.node_render_width - 9)); } +string TextTreeRenderer::RenderProfiler(const QueryProfiler &profiler) { + // the text profiler output is the framed query tree (header, total time, phase timings, operator tree) + return profiler.QueryTreeToString(); +} + } // namespace duckdb diff --git a/src/duckdb/src/common/types.cpp b/src/duckdb/src/common/types.cpp index d0b0867f3..6b1768af2 100644 --- a/src/duckdb/src/common/types.cpp +++ b/src/duckdb/src/common/types.cpp @@ -880,18 +880,6 @@ LogicalType LogicalType::NormalizeType(const LogicalType &type) { } } -class LogicalTypeResolver { -public: - explicit LogicalTypeResolver(optional_ptr context_p) : context(context_p) { - } - virtual ~LogicalTypeResolver() = default; - - virtual bool Operation(const LogicalType &left, const LogicalType &right, LogicalType &result) = 0; - -public: - optional_ptr context; -}; - static bool TryGetMaxLogicalTypeInternal(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, const LogicalType &right, LogicalType &result); @@ -915,74 +903,6 @@ class TryGetLogicalTypeResolver : public LogicalTypeResolver { } }; -static bool CombineNullOrUnknown(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, - LogicalType &result) { - // NULL/unknown (parameter) types always take the other type - if (left.id() == LogicalTypeId::SQLNULL || right.id() == LogicalTypeId::SQLNULL) { - result = LogicalType::NormalizeType(left.id() == LogicalTypeId::SQLNULL ? right : left); - } else { - result = LogicalType::NormalizeType(left.id() == LogicalTypeId::UNKNOWN ? right : left); - } - return true; -} - -static bool CombineEnum(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, const LogicalType &right, - LogicalType &result) { - // for enums, match the varchar rules - if (left.id() == LogicalTypeId::ENUM) { - return logical_type_resolver.Operation(LogicalType::VARCHAR, right, result); - } - return logical_type_resolver.Operation(left, LogicalType::VARCHAR, result); -} - -static bool CombineVariant(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, - LogicalType &result) { - result = right.id() == LogicalTypeId::VARIANT ? right : left; - return true; -} - -// for everything but enums - string literals also take the other type -static bool CombineStringLiteral(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, - LogicalType &result) { - result = LogicalType::NormalizeType(left.id() == LogicalTypeId::STRING_LITERAL ? right : left); - return true; -} - -using CombineTypesRuleFunction = bool (*)(LogicalTypeResolver &resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result); -struct CombineUnequalTypesRule { - bool (*matches)(const LogicalType &left, const LogicalType &right); // order-insensitive - CombineTypesRuleFunction function; -}; - -static bool MatchesVariant(const LogicalType &left, const LogicalType &right) { - return left.id() == LogicalTypeId::VARIANT || right.id() == LogicalTypeId::VARIANT; -} - -static bool MatchesNullOrUnknown(const LogicalType &left, const LogicalType &right) { - auto null_or_unknown = [](const LogicalType &type) { - return type.id() == LogicalTypeId::SQLNULL || type.id() == LogicalTypeId::UNKNOWN; - }; - return null_or_unknown(left) || null_or_unknown(right); -} - -static bool MatchesEnum(const LogicalType &left, const LogicalType &right) { - return left.id() == LogicalTypeId::ENUM || right.id() == LogicalTypeId::ENUM; -} - -static bool MatchesStringLiteral(const LogicalType &left, const LogicalType &right) { - return left.id() == LogicalTypeId::STRING_LITERAL || right.id() == LogicalTypeId::STRING_LITERAL; -} - -// Rules are matched in order, so the first matching rule wins (VARIANT and NULL/UNKNOWN are matched -// before ENUM, ENUM before STRING_LITERAL). Each `matches` predicate is order-insensitive in (left, right). -static const CombineUnequalTypesRule COMBINE_UNEQUAL_TYPES_RULES[] = { - {MatchesVariant, CombineVariant}, - {MatchesNullOrUnknown, CombineNullOrUnknown}, - {MatchesEnum, CombineEnum}, - {MatchesStringLiteral, CombineStringLiteral}, -}; - // Generic combine engine: try the implicit cast rules in both directions and keep the cheaper one. With a // context we go through CastFunctionSet so that any registered casts are honored; without a context we // consult the built-in CastRules table directly. Returns false when neither direction can be cast. @@ -1027,246 +947,53 @@ static bool TryCombineViaImplicitCast(LogicalTypeResolver &logical_type_resolver return false; } -static bool CombineUnequalTypes(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - D_ASSERT(right.id() != left.id()); - for (auto &combine_rule : COMBINE_UNEQUAL_TYPES_RULES) { - if (combine_rule.matches(left, right)) { - return combine_rule.function(logical_type_resolver, left, right, result); +static bool TryGetMaxLogicalTypeInternal(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + auto &optional_context = logical_type_resolver.context; + // with a context, check all combine rules, including ones registered by extensions + // without one, check only the built-in rules + bool success; + bool matched = optional_context + ? CastFunctionSet::Get(*optional_context) + .TryCombineTypes(logical_type_resolver, left, right, result, success) + : CastFunctionSet::TryCombineTypes(DefaultCombineTypesRules(), logical_type_resolver, left, + right, result, success); + if (matched) { + return success; + } + // unequal types fallthrough + if (left.id() != right.id()) { + // for other types - try to combine through the generic implicit cast rules + if (TryCombineViaImplicitCast(logical_type_resolver, left, right, result)) { + return true; } - } - - // for other types - try to combine through the generic implicit cast rules - if (TryCombineViaImplicitCast(logical_type_resolver, left, right, result)) { - return true; - } - // for integer literals - rerun the operation with the underlying type - if (left.id() == LogicalTypeId::INTEGER_LITERAL) { - return logical_type_resolver.Operation(IntegerLiteral::GetType(left), right, result); - } - if (right.id() == LogicalTypeId::INTEGER_LITERAL) { - return logical_type_resolver.Operation(left, IntegerLiteral::GetType(right), result); - } - // for unsigned/signed comparisons we have a few fallbacks - if (left.IsNumeric() && right.IsNumeric()) { - result = CombineNumericTypes(left, right); - return true; - } - if (left.id() == LogicalTypeId::BOOLEAN && right.IsIntegral()) { - result = right; - return true; - } - if (right.id() == LogicalTypeId::BOOLEAN && left.IsIntegral()) { - result = left; - return true; - } - return false; -} - -static bool CombineStructTypes(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - auto &left_children = StructType::GetChildTypes(left); - auto &right_children = StructType::GetChildTypes(right); - - auto left_unnamed = StructType::IsUnnamed(left); - auto is_unnamed = left_unnamed || StructType::IsUnnamed(right); - child_list_t child_types; - - // At least one side is unnamed, so we attempt positional casting. - if (is_unnamed) { - if (left_children.size() != right_children.size()) { - // We can't cast, or create the super-set. - return false; + // for integer literals - rerun the operation with the underlying type + if (left.id() == LogicalTypeId::INTEGER_LITERAL) { + return logical_type_resolver.Operation(IntegerLiteral::GetType(left), right, result); } - - for (idx_t i = 0; i < left_children.size(); i++) { - LogicalType child_type; - if (!logical_type_resolver.Operation(left_children[i].second, right_children[i].second, child_type)) { - return false; - } - auto &child_name = left_unnamed ? right_children[i].first : left_children[i].first; - child_types.emplace_back(child_name, std::move(child_type)); + if (right.id() == LogicalTypeId::INTEGER_LITERAL) { + return logical_type_resolver.Operation(left, IntegerLiteral::GetType(right), result); } - result = LogicalType::STRUCT(child_types); - return true; - } - - // Create a super-set of the STRUCT fields. - // First, create a name->index map of the right children. - InsertionOrderPreservingMap> right_children_map; - for (idx_t i = 0; i < right_children.size(); i++) { - auto &name = right_children[i].first; - right_children_map[name] = i; - } - - for (idx_t i = 0; i < left_children.size(); i++) { - auto &left_child = left_children[i]; - auto right_child_it = right_children_map.find(left_child.first); - - if (right_child_it == right_children_map.end()) { - // We can directly put the left child. - child_types.emplace_back(left_child.first, left_child.second); - continue; + // for unsigned/signed comparisons we have a few fallbacks + if (left.IsNumeric() && right.IsNumeric()) { + result = CombineNumericTypes(left, right); + return true; } - - // We need to recurse to ensure the children have a maximum logical type. - LogicalType child_type; - auto &right_child = right_children[right_child_it->second]; - if (!logical_type_resolver.Operation(left_child.second, right_child.second, child_type)) { - return false; + if (left.id() == LogicalTypeId::BOOLEAN && right.IsIntegral()) { + result = right; + return true; } - child_types.emplace_back(left_child.first, std::move(child_type)); - right_children_map.erase(right_child_it); - } - - // Add all remaining right children. - for (const auto &right_child_it : right_children_map) { - auto &right_child = right_children[right_child_it.second]; - child_types.emplace_back(right_child.first, right_child.second); - } - - result = LogicalType::STRUCT(child_types); - return true; -} - -struct CombineEqualTypesRule { - LogicalTypeId type; - CombineTypesRuleFunction function; -}; - -static bool CombineEqualStringLiteral(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - result = LogicalType::VARCHAR; - return true; -} -static bool CombineEqualIntegerLiteral(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // for two integer literals we unify the underlying types - return logical_type_resolver.Operation(IntegerLiteral::GetType(left), IntegerLiteral::GetType(right), result); -} -static bool CombineEqualEnum(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // If both types are different ENUMs we do a string comparison. - result = left == right ? left : LogicalType::VARCHAR; - return true; -} -static bool CombineEqualVarchar(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // varchar: use type that has collation (if any) - if (StringType::GetCollation(right).empty()) { - result = left; - } else { - result = right; - } - return true; -} -static bool CombineEqualDecimal(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // unify the width/scale so that the resulting decimal always fits - // "width - scale" gives us the number of digits on the left side of the decimal point - // "scale" gives us the number of digits allowed on the right of the decimal point - // using the max of these of the two types gives us the new decimal size - auto extra_width_left = DecimalType::GetWidth(left) - DecimalType::GetScale(left); - auto extra_width_right = DecimalType::GetWidth(right) - DecimalType::GetScale(right); - auto extra_width = - MaxValue(NumericCast(extra_width_left), NumericCast(extra_width_right)); - auto scale = MaxValue(DecimalType::GetScale(left), DecimalType::GetScale(right)); - auto width = NumericCast(extra_width + scale); - if (width > DecimalType::MaxWidth()) { - // if the resulting decimal does not fit, we truncate the scale - width = DecimalType::MaxWidth(); - scale = NumericCast(width - extra_width); - } - result = LogicalType::DECIMAL(width, scale); - return true; -} -static bool CombineEqualList(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // list: perform max recursively on child type - LogicalType new_child; - if (!logical_type_resolver.Operation(ListType::GetChildType(left), ListType::GetChildType(right), new_child)) { - return false; - } - result = LogicalType::LIST(new_child); - return true; -} -static bool CombineEqualArray(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - LogicalType new_child; - if (!logical_type_resolver.Operation(ArrayType::GetChildType(left), ArrayType::GetChildType(right), new_child)) { - return false; - } - auto new_size = MaxValue(ArrayType::GetSize(left), ArrayType::GetSize(right)); - result = LogicalType::ARRAY(new_child, new_size); - return true; -} -static bool CombineEqualMap(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // map: perform max recursively on child type - LogicalType new_child; - if (!logical_type_resolver.Operation(ListType::GetChildType(left), ListType::GetChildType(right), new_child)) { - return false; - } - result = LogicalType::MAP(new_child); - return true; -} -static bool CombineEqualUnion(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - auto left_member_count = UnionType::GetMemberCount(left); - auto right_member_count = UnionType::GetMemberCount(right); - if (left_member_count != right_member_count) { - // return the "larger" type, with the most members - result = left_member_count > right_member_count ? left : right; - return true; - } - // otherwise, keep left, don't try to meld the two together. - result = left; - return true; -} - -static const CombineEqualTypesRule COMBINE_EQUAL_TYPES_RULES[] = { - {LogicalTypeId::STRING_LITERAL, CombineEqualStringLiteral}, - {LogicalTypeId::INTEGER_LITERAL, CombineEqualIntegerLiteral}, - {LogicalTypeId::ENUM, CombineEqualEnum}, - {LogicalTypeId::VARCHAR, CombineEqualVarchar}, - {LogicalTypeId::DECIMAL, CombineEqualDecimal}, - {LogicalTypeId::LIST, CombineEqualList}, - {LogicalTypeId::ARRAY, CombineEqualArray}, - {LogicalTypeId::MAP, CombineEqualMap}, - {LogicalTypeId::STRUCT, CombineStructTypes}, - {LogicalTypeId::UNION, CombineEqualUnion}, -}; - -static bool CombineEqualTypes(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - auto type_id = left.id(); - for (auto &combine_rule : COMBINE_EQUAL_TYPES_RULES) { - if (type_id == combine_rule.type) { - return combine_rule.function(logical_type_resolver, left, right, result); + if (right.id() == LogicalTypeId::BOOLEAN && left.IsIntegral()) { + result = left; + return true; } + return false; } + // equal types fallthrough result = left; return true; } -static bool TryGetMaxLogicalTypeInternal(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, - const LogicalType &right, LogicalType &result) { - // we always prefer aliased types - if (!left.GetAlias().empty()) { - result = left; - return true; - } - if (!right.GetAlias().empty()) { - result = right; - return true; - } - if (left.id() != right.id()) { - return CombineUnequalTypes(logical_type_resolver, left, right, result); - } else { - return CombineEqualTypes(logical_type_resolver, left, right, result); - } -} - bool LogicalType::TryGetMaxLogicalType(ClientContext &context, const LogicalType &left, const LogicalType &right, LogicalType &result) { if (Settings::Get(context)) { @@ -1537,7 +1264,8 @@ LogicalType LogicalType::Deserialize(Deserializer &deserializer) { LogicalType LogicalType::Copy() const { LogicalType copy = *this; if (type_info_ && type_info_->type != ExtraTypeInfoType::ENUM_TYPE_INFO) { - // We copy (i.e., create new) type info, unless the type is an ENUM, otherwise we have to copy the whole dict + // We copy (i.e., create new) type info, unless the type is an ENUM - enum type info is kept shared to avoid + // rebuilding the dictionary lookup map; use DeepCopy to force a copy copy.type_info_ = type_info_->Copy(); } return copy; @@ -1545,8 +1273,7 @@ LogicalType LogicalType::Copy() const { LogicalType LogicalType::DeepCopy() const { LogicalType copy = *this; - if (type_info_ && type_info_->type != ExtraTypeInfoType::ENUM_TYPE_INFO) { - // We copy (i.e., create new) type info, unless the type is an ENUM, otherwise we have to copy the whole dict + if (type_info_) { copy.type_info_ = type_info_->DeepCopy(); } return copy; @@ -2054,10 +1781,11 @@ LogicalType LogicalType::GEOMETRY(const CoordinateReferenceSystem &crs) { bool GeoType::HasCRS(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::GEOMETRY); auto info = type.AuxInfo(); - if (!info) { + if (!info || info->type != ExtraTypeInfoType::GEO_TYPE_INFO) { + // a GEOMETRY type without geo type info has no CRS - this can happen when an alias is set on a geometry + // type that was created without a CRS (SetAlias attaches a generic type info) return false; } - D_ASSERT(info->type == ExtraTypeInfoType::GEO_TYPE_INFO); const auto &geo_info = info->Cast(); return geo_info.crs.GetType() != CoordinateReferenceSystemType::INVALID; @@ -2066,11 +1794,9 @@ bool GeoType::HasCRS(const LogicalType &type) { const CoordinateReferenceSystem &GeoType::GetCRS(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::GEOMETRY); auto info = type.AuxInfo(); - if (!info) { + if (!info || info->type != ExtraTypeInfoType::GEO_TYPE_INFO) { throw InternalException("Geometry type has no CRS information"); } - D_ASSERT(info); - D_ASSERT(info->type == ExtraTypeInfoType::GEO_TYPE_INFO); auto &geo_info = info->Cast(); return geo_info.crs; diff --git a/src/duckdb/src/common/types/list_segment.cpp b/src/duckdb/src/common/types/list_segment.cpp index c9f037838..e80feebb9 100644 --- a/src/duckdb/src/common/types/list_segment.cpp +++ b/src/duckdb/src/common/types/list_segment.cpp @@ -50,6 +50,10 @@ static char *GetStringData(ListSegment *segment) { return reinterpret_cast(data_ptr_cast(segment) + sizeof(ListSegment)); } +static const char *GetStringData(const ListSegment *segment) { + return reinterpret_cast(const_data_ptr_cast(segment) + sizeof(ListSegment)); +} + //===--------------------------------------------------------------------===// // Lists //===--------------------------------------------------------------------===// @@ -386,174 +390,327 @@ void ListSegmentFunctions::AppendRow(ArenaAllocator &allocator, LinkedList &link segment->count++; } +void ListSegmentFunctions::AppendListEntry(ArenaAllocator &allocator, LinkedList &linked_list, + RecursiveUnifiedVectorFormat &child_data, + const list_entry_t &list_entry) const { + for (idx_t child_idx = list_entry.offset; child_idx < list_entry.offset + list_entry.length; child_idx++) { + allocator.AlignNext(); + AppendRow(allocator, linked_list, child_data, child_idx); + } +} + //===--------------------------------------------------------------------===// -// Read +// Scan //===--------------------------------------------------------------------===// +//! Move the scan state to the next segment of the linked list (clearing any child scan states) +static void MoveToNextSegment(ListSegmentScanState &state) { + state.segment = state.segment->next; + state.offset = 0; + state.children.clear(); +} + template -static void ReadDataFromPrimitiveSegment(const ListSegmentFunctions &, const ListSegment *segment, Vector &result, - idx_t &total_count) { +static idx_t ScanPrimitiveData(const ListSegmentFunctions &, ListSegmentScanState &state, idx_t count, Vector &result, + idx_t result_offset) { auto &aggr_vector_validity = FlatVector::ValidityMutable(result); - - // set NULLs - auto null_mask = GetNullMask(segment); - for (idx_t i = 0; i < segment->count; i++) { - if (null_mask[i]) { - aggr_vector_validity.SetInvalid(total_count + i); - } - } - auto aggr_vector_data = FlatVector::GetDataMutable(result); - // load values - for (idx_t i = 0; i < segment->count; i++) { - if (aggr_vector_validity.RowIsValid(total_count + i)) { - auto data = GetPrimitiveData(segment); - aggr_vector_data[total_count + i] = Load(const_data_ptr_cast(data + i)); + idx_t total_read = 0; + while (total_read < count && state.segment) { + auto segment = state.segment; + auto read_count = MinValue(count - total_read, segment->count - state.offset); + auto null_mask = GetNullMask(segment); + auto data = GetPrimitiveData(segment); + for (idx_t i = 0; i < read_count; i++) { + auto source_idx = state.offset + i; + auto target_idx = result_offset + total_read + i; + if (null_mask[source_idx]) { + aggr_vector_validity.SetInvalid(target_idx); + } else { + aggr_vector_data[target_idx] = Load(const_data_ptr_cast(data + source_idx)); + } + } + total_read += read_count; + state.offset += read_count; + if (state.offset == segment->count) { + MoveToNextSegment(state); } } + return total_read; } -static void ReadDataFromVarcharSegment(const ListSegmentFunctions &, const ListSegment *segment, Vector &result, - idx_t &total_count) { +static idx_t ScanVarcharData(const ListSegmentFunctions &, ListSegmentScanState &state, idx_t count, Vector &result, + idx_t result_offset) { auto &aggr_vector_validity = FlatVector::ValidityMutable(result); - - // use length and (reconstructed) offset to get the correct substrings auto aggr_vector_data = FlatVector::GetDataMutable(result); - auto str_length_data = GetListLengthData(segment); - auto null_mask = GetNullMask(segment); - auto linked_child_list = Load(const_data_ptr_cast(GetListChildData(segment))); - auto current_segment = linked_child_list.first_segment; - idx_t child_offset = 0; - for (idx_t i = 0; i < segment->count; i++) { - if (null_mask[i]) { - // set to null - aggr_vector_validity.SetInvalid(total_count + i); - continue; + idx_t total_read = 0; + while (total_read < count && state.segment) { + auto segment = state.segment; + if (state.children.empty()) { + // entering this segment - point the child state at the start of the segment's character data + auto linked_child_list = Load(const_data_ptr_cast(GetListChildData(segment))); + state.children.emplace_back(); + state.children.back().segment = linked_child_list.first_segment; } - // read the string - auto &result_str = aggr_vector_data[total_count + i]; - auto str_length = Load(const_data_ptr_cast(str_length_data + i)); - // allocate an empty string for the given size - result_str = StringVector::EmptyString(result, str_length); - auto result_data = result_str.GetDataWriteable(); - // copy over the data - idx_t current_offset = 0; - while (current_offset < str_length) { - if (!current_segment) { - throw InternalException("Insufficient data to read string"); + auto &child_state = state.children.back(); + auto read_count = MinValue(count - total_read, segment->count - state.offset); + auto null_mask = GetNullMask(segment); + auto str_length_data = GetListLengthData(segment); + for (idx_t i = 0; i < read_count; i++) { + auto source_idx = state.offset + i; + auto target_idx = result_offset + total_read + i; + if (null_mask[source_idx]) { + // set to null + aggr_vector_validity.SetInvalid(target_idx); + continue; } - auto child_data = GetStringData(current_segment); - idx_t max_copy = MinValue(str_length - current_offset, current_segment->capacity - child_offset); - memcpy(result_data + current_offset, child_data + child_offset, max_copy); - current_offset += max_copy; - child_offset += max_copy; - if (child_offset >= current_segment->capacity) { - D_ASSERT(child_offset == current_segment->capacity); - current_segment = current_segment->next; - child_offset = 0; + // read the string + auto &result_str = aggr_vector_data[target_idx]; + auto str_length = Load(const_data_ptr_cast(str_length_data + source_idx)); + if (child_state.segment && child_state.offset + str_length <= child_state.segment->capacity) { + // the string fits in the current segment - reference it directly instead of copying + result_str = string_t(GetStringData(child_state.segment) + child_state.offset, + NumericCast(str_length)); + child_state.offset += str_length; + if (child_state.offset == child_state.segment->capacity) { + child_state.segment = child_state.segment->next; + child_state.offset = 0; + } + continue; + } + // allocate an empty string for the given size + result_str = StringVector::EmptyString(result, str_length); + auto result_data = result_str.GetDataWriteable(); + idx_t current_offset = 0; + while (current_offset < str_length) { + if (!child_state.segment) { + throw InternalException("Insufficient data to read string"); + } + auto child_data = GetStringData(child_state.segment); + idx_t max_copy = + MinValue(str_length - current_offset, child_state.segment->capacity - child_state.offset); + memcpy(result_data + current_offset, child_data + child_state.offset, max_copy); + current_offset += max_copy; + child_state.offset += max_copy; + if (child_state.offset >= child_state.segment->capacity) { + D_ASSERT(child_state.offset == child_state.segment->capacity); + child_state.segment = child_state.segment->next; + child_state.offset = 0; + } } - } - // finalize the str - result_str.Finalize(); + // finalize the str + result_str.Finalize(); + } + total_read += read_count; + state.offset += read_count; + if (state.offset == segment->count) { + MoveToNextSegment(state); + } } + return total_read; } -static void ReadDataFromListSegment(const ListSegmentFunctions &functions, const ListSegment *segment, Vector &result, - idx_t &total_count) { +static idx_t ScanListData(const ListSegmentFunctions &functions, ListSegmentScanState &state, idx_t count, + Vector &result, idx_t result_offset) { auto &aggr_vector_validity = FlatVector::ValidityMutable(result); + auto list_vector_data = FlatVector::GetDataMutable(result); - // set NULLs - auto null_mask = GetNullMask(segment); - for (idx_t i = 0; i < segment->count; i++) { - if (null_mask[i]) { - aggr_vector_validity.SetInvalid(total_count + i); + D_ASSERT(functions.child_functions.size() == 1); + auto &child_function = functions.child_functions[0]; + + idx_t total_read = 0; + while (total_read < count && state.segment) { + auto segment = state.segment; + if (state.children.empty()) { + // entering this segment - point the child state at the start of the segment's child values + auto linked_child_list = Load(const_data_ptr_cast(GetListChildData(segment))); + state.children.emplace_back(); + state.children.back().segment = linked_child_list.first_segment; + } + auto &child_state = state.children.back(); + auto read_count = MinValue(count - total_read, segment->count - state.offset); + auto null_mask = GetNullMask(segment); + auto list_length_data = GetListLengthData(segment); + + // get the starting offset in the result child vector + auto current_result_offset = result_offset + total_read; + idx_t offset = 0; + if (current_result_offset != 0) { + offset = + list_vector_data[current_result_offset - 1].offset + list_vector_data[current_result_offset - 1].length; + } + idx_t starting_offset = offset; + + // set length and offsets + for (idx_t i = 0; i < read_count; i++) { + auto source_idx = state.offset + i; + auto target_idx = current_result_offset + i; + if (null_mask[source_idx]) { + aggr_vector_validity.SetInvalid(target_idx); + } + auto list_length = Load(const_data_ptr_cast(list_length_data + source_idx)); + list_vector_data[target_idx].length = list_length; + list_vector_data[target_idx].offset = offset; + offset += list_length; } - } - auto list_vector_data = FlatVector::GetDataMutable(result); + ListVector::Reserve(result, offset); + auto &child_vector = ListVector::GetChildMutable(result); - // get the starting offset - idx_t offset = 0; - if (total_count != 0) { - offset = list_vector_data[total_count - 1].offset + list_vector_data[total_count - 1].length; - } - idx_t starting_offset = offset; + // recurse into the linked list of child values + auto child_read = child_function.scan_data(child_function, child_state, offset - starting_offset, child_vector, + starting_offset); + if (child_read != offset - starting_offset) { + throw InternalException("Insufficient data in linked list to read list entries"); + } + ListVector::SetListSize(result, offset); - // set length and offsets - auto list_length_data = GetListLengthData(segment); - for (idx_t i = 0; i < segment->count; i++) { - auto list_length = Load(const_data_ptr_cast(list_length_data + i)); - list_vector_data[total_count + i].length = list_length; - list_vector_data[total_count + i].offset = offset; - offset += list_length; + total_read += read_count; + state.offset += read_count; + if (state.offset == segment->count) { + MoveToNextSegment(state); + } } - - auto &child_vector = ListVector::GetChildMutable(result); - auto linked_child_list = Load(const_data_ptr_cast(GetListChildData(segment))); - ListVector::Reserve(result, offset); - - // recurse into the linked list of child values - D_ASSERT(functions.child_functions.size() == 1); - functions.child_functions[0].BuildListVector(linked_child_list, child_vector, starting_offset); - ListVector::SetListSize(result, offset); + return total_read; } -static void ReadDataFromStructSegment(const ListSegmentFunctions &functions, const ListSegment *segment, Vector &result, - idx_t &total_count) { +static idx_t ScanStructData(const ListSegmentFunctions &functions, ListSegmentScanState &state, idx_t count, + Vector &result, idx_t result_offset) { auto &aggr_vector_validity = FlatVector::ValidityMutable(result); + auto &children = StructVector::GetEntries(result); + D_ASSERT(children.size() == functions.child_functions.size()); - // set NULLs - auto null_mask = GetNullMask(segment); - for (idx_t i = 0; i < segment->count; i++) { - if (null_mask[i]) { - aggr_vector_validity.SetInvalid(total_count + i); + idx_t total_read = 0; + while (total_read < count && state.segment) { + auto segment = state.segment; + if (state.children.empty()) { + // entering this segment - point the child states at the segment's child segments + auto struct_children = GetStructData(segment); + state.children.resize(children.size()); + for (idx_t child_idx = 0; child_idx < children.size(); child_idx++) { + state.children[child_idx].segment = + Load(const_data_ptr_cast(struct_children + child_idx)); + } + } + auto read_count = MinValue(count - total_read, segment->count - state.offset); + auto null_mask = GetNullMask(segment); + for (idx_t i = 0; i < read_count; i++) { + if (null_mask[state.offset + i]) { + aggr_vector_validity.SetInvalid(result_offset + total_read + i); + } } - } - auto &children = StructVector::GetEntries(result); + // recurse into the child segments of each child of the struct + // the child segments are aligned with the parent segment, so they advance in lockstep + for (idx_t child_idx = 0; child_idx < children.size(); child_idx++) { + auto &child_function = functions.child_functions[child_idx]; + child_function.scan_data(child_function, state.children[child_idx], read_count, children[child_idx], + result_offset + total_read); + } - // recurse into the child segments of each child of the struct - D_ASSERT(children.size() == functions.child_functions.size()); - auto struct_children = GetStructData(segment); - for (idx_t child_count = 0; child_count < children.size(); child_count++) { - auto struct_children_segment = Load(const_data_ptr_cast(struct_children + child_count)); - auto &child_function = functions.child_functions[child_count]; - child_function.read_data(child_function, struct_children_segment, children[child_count], total_count); + total_read += read_count; + state.offset += read_count; + if (state.offset == segment->count) { + MoveToNextSegment(state); + } } + return total_read; } -static void ReadDataFromArraySegment(const ListSegmentFunctions &functions, const ListSegment *segment, Vector &result, - idx_t &total_count) { +static idx_t ScanArrayData(const ListSegmentFunctions &functions, ListSegmentScanState &state, idx_t count, + Vector &result, idx_t result_offset) { auto &aggr_vector_validity = FlatVector::ValidityMutable(result); + auto &child_vector = ArrayVector::GetChildMutable(result); + auto array_size = ArrayType::GetSize(result.GetType()); - // set NULLs - auto null_mask = GetNullMask(segment); - for (idx_t i = 0; i < segment->count; i++) { - if (null_mask[i]) { - aggr_vector_validity.SetInvalid(total_count + i); + D_ASSERT(functions.child_functions.size() == 1); + auto &child_function = functions.child_functions[0]; + + idx_t total_read = 0; + while (total_read < count && state.segment) { + auto segment = state.segment; + if (state.children.empty()) { + // entering this segment - point the child state at the start of the segment's child values + auto linked_child_list = Load(const_data_ptr_cast(GetArrayChildData(segment))); + state.children.emplace_back(); + state.children.back().segment = linked_child_list.first_segment; + } + auto &child_state = state.children.back(); + auto read_count = MinValue(count - total_read, segment->count - state.offset); + auto null_mask = GetNullMask(segment); + for (idx_t i = 0; i < read_count; i++) { + if (null_mask[state.offset + i]) { + aggr_vector_validity.SetInvalid(result_offset + total_read + i); + } + } + + // recurse into the linked list of child values + child_function.scan_data(child_function, child_state, read_count * array_size, child_vector, + (result_offset + total_read) * array_size); + + total_read += read_count; + state.offset += read_count; + if (state.offset == segment->count) { + MoveToNextSegment(state); } } + return total_read; +} - auto &child_vector = ArrayVector::GetChildMutable(result); - auto linked_child_list = Load(const_data_ptr_cast(GetArrayChildData(segment))); - auto array_size = ArrayType::GetSize(result.GetType()); - auto child_size = array_size * total_count; +void ListSegmentFunctions::InitializeScan(const LinkedList &linked_list, ListSegmentScanState &state) const { + state.segment = linked_list.first_segment; + state.offset = 0; + state.children.clear(); +} - // recurse into the linked list of child values - D_ASSERT(functions.child_functions.size() == 1); - functions.child_functions[0].BuildListVector(linked_child_list, child_vector, child_size); +idx_t ListSegmentFunctions::Scan(ListSegmentScanState &state, Vector &result) const { + return scan_data(*this, state, STANDARD_VECTOR_SIZE, result, 0); } void ListSegmentFunctions::BuildListVector(const LinkedList &linked_list, Vector &result, idx_t total_count) const { - auto &read_data_from_segment = *this; - auto segment = linked_list.first_segment; - while (segment) { - read_data_from_segment.read_data(read_data_from_segment, segment, result, total_count); - total_count += segment->count; - segment = segment->next; + ListSegmentScanState state; + InitializeScan(linked_list, state); + scan_data(*this, state, NumericLimits::Maximum(), result, total_count); +} + +void ListSegmentFunctions::BuildLists(const vector &linked_lists, Vector &result, idx_t offset) const { + D_ASSERT(result.GetType().id() == LogicalTypeId::LIST); + const idx_t count = linked_lists.size(); + + auto &mask = FlatVector::ValidityMutable(result); + auto result_data = FlatVector::ScatterWriter(result); + idx_t total_len = ListVector::GetListSize(result); + + // first iterate over all entries and set up the list entries, and get the newly required total length + for (idx_t i = 0; i < count; i++) { + auto &linked_list = linked_lists[i]; + const auto rid = offset + i; + result_data[rid].offset = total_len; + if (linked_list.total_capacity == 0) { + // empty linked list - set the result row to NULL + mask.SetInvalid(rid); + result_data[rid].length = 0; + continue; + } + result_data[rid].length = linked_list.total_capacity; + total_len += linked_list.total_capacity; + } + + // reserve capacity, then iterate over all entries again and copy over the data to the child vector + ListVector::Reserve(result, total_len); + auto &result_child = ListVector::GetChildMutable(result); + for (idx_t i = 0; i < count; i++) { + auto &linked_list = linked_lists[i]; + if (linked_list.total_capacity == 0) { + continue; + } + BuildListVector(linked_list, result_child, result_data[offset + i].offset); } + + ListVector::SetListSize(result, total_len); + FlatVector::SetSize(result, offset + count); } //===--------------------------------------------------------------------===// @@ -563,7 +720,7 @@ template void SegmentPrimitiveFunction(ListSegmentFunctions &functions) { functions.create_segment = CreatePrimitiveSegment; functions.write_data = WriteDataToPrimitiveSegment; - functions.read_data = ReadDataFromPrimitiveSegment; + functions.scan_data = ScanPrimitiveData; } void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType &type) { @@ -622,12 +779,12 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType case PhysicalType::VARCHAR: { functions.create_segment = CreateListSegment; functions.write_data = WriteDataToVarcharSegment; - functions.read_data = ReadDataFromVarcharSegment; + functions.scan_data = ScanVarcharData; ListSegmentFunctions child_function; child_function.create_segment = CreateVarcharDataSegment; child_function.write_data = nullptr; - child_function.read_data = nullptr; + child_function.scan_data = nullptr; child_function.initial_capacity = 16; functions.child_functions.push_back(child_function); break; @@ -635,7 +792,7 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType case PhysicalType::LIST: { functions.create_segment = CreateListSegment; functions.write_data = WriteDataToListSegment; - functions.read_data = ReadDataFromListSegment; + functions.scan_data = ScanListData; // recurse functions.child_functions.emplace_back(); @@ -645,7 +802,7 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType case PhysicalType::STRUCT: { functions.create_segment = CreateStructSegment; functions.write_data = WriteDataToStructSegment; - functions.read_data = ReadDataFromStructSegment; + functions.scan_data = ScanStructData; // recurse auto child_types = StructType::GetChildTypes(type); @@ -658,7 +815,7 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType case PhysicalType::ARRAY: { functions.create_segment = CreateArraySegment; functions.write_data = WriteDataToArraySegment; - functions.read_data = ReadDataFromArraySegment; + functions.scan_data = ScanArrayData; // recurse functions.child_functions.emplace_back(); diff --git a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp index 7b91065fc..bf09e17ad 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp @@ -2566,6 +2566,16 @@ void PhysicalCopyToFile::ReturnStatistics(DataChunk &chunk, CopyToFileInfo &info // partition_keys map(varchar, varchar) chunk.data[5].Append(info.partition_keys); + + // extra info map(varchar, variant) + vector extra_keys; + vector extra_values; + for (auto &entry : file_stats.extra_info) { + extra_keys.emplace_back(entry.first); + extra_values.push_back(entry.second.DefaultCastAs(LogicalType::VARIANT())); + } + chunk.data[6].Append( + Value::MAP(LogicalType::VARCHAR, LogicalType::VARIANT(), std::move(extra_keys), std::move(extra_values))); } bool PhysicalCopyToFile::Rotate() const { diff --git a/src/duckdb/src/execution/physical_operator.cpp b/src/duckdb/src/execution/physical_operator.cpp index b1416b2aa..e8c5066df 100644 --- a/src/duckdb/src/execution/physical_operator.cpp +++ b/src/duckdb/src/execution/physical_operator.cpp @@ -28,8 +28,12 @@ string PhysicalOperator::GetName() const { return PhysicalOperatorToString(type); } -string PhysicalOperator::ToString(ExplainFormat format) const { +string PhysicalOperator::ToString(const ProfilerPrintFormat &format) const { auto renderer = TreeRenderer::CreateRenderer(format); + if (!renderer) { + // formats without output (e.g. "no_output") render nothing + return string(); + } stringstream ss; auto tree = RenderTree::CreateRenderTree(*this); renderer->ToStream(*tree, ss); diff --git a/src/duckdb/src/execution/physical_plan/plan_explain.cpp b/src/duckdb/src/execution/physical_plan/plan_explain.cpp index 319ad69d8..acfed115b 100644 --- a/src/duckdb/src/execution/physical_plan/plan_explain.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_explain.cpp @@ -10,16 +10,16 @@ namespace duckdb { PhysicalOperator &PhysicalPlanGenerator::CreatePlan(LogicalExplain &op) { D_ASSERT(op.children.size() == 1); - auto logical_plan_opt = op.children[0]->ToString(op.explain_format); + auto logical_plan_opt = op.children[0]->ToString(op.format); auto &plan = CreatePlan(*op.children[0]); if (op.explain_type == ExplainType::EXPLAIN_ANALYZE) { - auto &explain = Make(op.types, op.explain_format); + auto &explain = Make(op.types, op.format); explain.children.push_back(plan); return explain; } // Format the plan and set the output of the EXPLAIN. - op.physical_plan = plan.ToString(op.explain_format); + op.physical_plan = plan.ToString(op.format); vector keys, values; switch (Settings::Get(context)) { case ExplainOutputType::OPTIMIZED_ONLY: diff --git a/src/duckdb/src/function/aggregate/distributive/decimal_avg.cpp b/src/duckdb/src/function/aggregate/distributive/decimal_avg.cpp new file mode 100644 index 000000000..3cbb1a25d --- /dev/null +++ b/src/duckdb/src/function/aggregate/distributive/decimal_avg.cpp @@ -0,0 +1,170 @@ +#include "duckdb/common/exception.hpp" +#include "duckdb/common/hugeint.hpp" +#include "duckdb/common/types/decimal.hpp" +#include "duckdb/common/types/uhugeint.hpp" +#include "duckdb/function/aggregate/distributive_functions.hpp" +#include "duckdb/function/aggregate/distributive_function_utils.hpp" +#include "duckdb/function/aggregate_function.hpp" +#include "duckdb/planner/expression.hpp" + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// State: running scaled-integer sum and a non-NULL row count. +// count == 0 is the empty-group sentinel (no separate boolean needed). +//===--------------------------------------------------------------------===// + +struct DecimalAvgState { + static constexpr const char *STATE_NAMES[] = {"sum", "count"}; + using STATE_TYPE = StructStateType; + + hugeint_t sum; // accumulated integer value at the input's scale + uint64_t count; // number of non-NULL rows accumulated so far +}; + +//===--------------------------------------------------------------------===// +// Operation +//===--------------------------------------------------------------------===// + +template +struct DecimalAvgOperation { + static bool IgnoreNull() { + return true; + } + + static void Initialize(DecimalAvgState &state) { + state.sum = hugeint_t(0); + state.count = 0; + } + + template + static void Operation(STATE &state, const INPUT &input, AggregateUnaryInput &) { + if (!Hugeint::TryAddInPlace(state.sum, hugeint_t(input))) { + throw OutOfRangeException("decimal_average: intermediate sum overflowed HUGEINT range"); + } + state.count++; + } + + template + static void ConstantOperation(STATE &state, const INPUT &input, AggregateUnaryInput &unary_input, idx_t count) { + for (idx_t i = 0; i < count; i++) { + Operation(state, input, unary_input); + } + } + + template + static void Combine(const STATE &source, STATE &target, AggregateInputData &) { + if (!Hugeint::TryAddInPlace(target.sum, source.sum)) { + throw OutOfRangeException("decimal_average: intermediate sum overflowed HUGEINT range during combine"); + } + target.count += source.count; + } + + // Overload for hugeint_t result: direct assignment. + static void AssignResult(hugeint_t &target, hugeint_t signed_q) { + target = signed_q; + } + + // Overload for smaller integer result types: take lower 64 bits. + // Safe because the average of values bounded by the type's range is also + // within that range. + template + static void AssignResult(RESULT &target, hugeint_t signed_q) { + target = static_cast(signed_q.lower); + } + + template + static void Finalize(STATE &state, RESULT &target, AggregateFinalizeData &fd) { + if (state.count == 0) { + fd.ReturnNull(); + return; + } + + bool negative = state.sum.upper < 0; + uhugeint_t abs_sum(static_cast(state.sum.upper), state.sum.lower); + if (negative) { + abs_sum = -abs_sum; + } + + uhugeint_t remainder; + uhugeint_t q = Uhugeint::DivMod(abs_sum, uhugeint_t(state.count), remainder); + auto r64 = remainder.lower; + + // Banker's rounding (round-half-to-even). + uint64_t dist = state.count - r64; + bool round_up = (dist < r64) | ((dist == r64) & static_cast(q.lower & 1)); + if (round_up) { + q = q + uhugeint_t(1); + } + + auto signed_q = hugeint_t(q); + if (negative) { + signed_q = hugeint_t(-q); + } + AssignResult(target, signed_q); + } +}; + +//===--------------------------------------------------------------------===// +// Registration +//===--------------------------------------------------------------------===// + +template +static AggregateFunction MakeDecimalAvgFunction(const LogicalType &input_type, const LogicalType &return_type) { + return AggregateFunction::UnaryAggregate>( + input_type, return_type); +} + +static unique_ptr BindDecimalAverage(BindAggregateFunctionInput &input) { + auto &function = input.GetBoundFunction(); + auto &arguments = input.GetArguments(); + auto &input_type = arguments[0]->GetReturnType(); + + if (input_type.id() == LogicalTypeId::UNKNOWN) { + return nullptr; + } + if (input_type.id() != LogicalTypeId::DECIMAL) { + throw InvalidInputException("decimal_average requires a DECIMAL argument, got %s — " + "cast the input explicitly, e.g. col::DECIMAL(18,2)", + input_type.ToString()); + } + + uint8_t width = DecimalType::GetWidth(input_type); + uint8_t scale = DecimalType::GetScale(input_type); + auto return_type = LogicalType::DECIMAL(width, scale); + + auto name = function.GetName(); + switch (input_type.InternalType()) { + case PhysicalType::INT16: + function.ReplaceImplementation( + MakeDecimalAvgFunction(LogicalType::DECIMAL(Decimal::MAX_WIDTH_INT16, scale), return_type)); + break; + case PhysicalType::INT32: + function.ReplaceImplementation( + MakeDecimalAvgFunction(LogicalType::DECIMAL(Decimal::MAX_WIDTH_INT32, scale), return_type)); + break; + case PhysicalType::INT64: + function.ReplaceImplementation( + MakeDecimalAvgFunction(LogicalType::DECIMAL(Decimal::MAX_WIDTH_INT64, scale), return_type)); + break; + case PhysicalType::INT128: + function.ReplaceImplementation( + MakeDecimalAvgFunction(LogicalType::DECIMAL(Decimal::MAX_WIDTH_DECIMAL, scale), return_type)); + break; + default: + throw InternalException("decimal_average: unexpected physical type"); + } + function.SetName(std::move(name)); + function.GetArguments()[0] = input_type; + return nullptr; +} + +AggregateFunctionSet DecimalAverageFun::GetFunctions() { + AggregateFunctionSet set("decimal_average"); + set.AddFunction(AggregateFunction({LogicalType(LogicalTypeId::DECIMAL)}, LogicalType(LogicalTypeId::DECIMAL), + nullptr, nullptr, nullptr, nullptr, nullptr, + FunctionNullHandling::DEFAULT_NULL_HANDLING, nullptr, BindDecimalAverage)); + return set; +} + +} // namespace duckdb diff --git a/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp b/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp index 7d987aa60..a80313bfa 100644 --- a/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp +++ b/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp @@ -9,15 +9,64 @@ namespace duckdb { namespace { +//! The aggregate state of first/last/any_value is nullable on two levels: the state itself is NULL when no row has +//! been seen yet (is_set, the outer optional), and the recorded value can itself be NULL (value_is_valid, the inner +//! optional). Valid exported states are e.g. NULL, {'value': NULL} and {'value': 42}. template struct FirstState { - static constexpr const char *STATE_NAMES[] = {"value", "is_set", "is_null"}; - using STATE_TYPE = StructStateType; + static constexpr const char *STATE_NAMES[] = {"value"}; + //! The value is exported with the aggregate's return type (e.g. DATE or UUID instead of the physical type) + using STATE_TYPE = OptionalStateType>>>; using VALUE_TYPE = T; T value; + //! Whether the recorded value is valid (i.e. not NULL) + bool value_is_valid; + //! Whether the state has been set (i.e. we have seen a row) bool is_set; - bool is_null; +}; + +//! String state variant: strings are stored in the arena allocator, re-using the previous allocation +//! when overwriting the value (relevant for last, which overwrites the value for every row). +struct FirstStringStateBase { + string_t value; + //! Whether the recorded value is valid (i.e. not NULL) + bool value_is_valid; + //! Whether the state has been set (i.e. we have seen a row) + bool is_set; + //! The size of the arena allocation for a non-inlined string value - not part of the exported state + uint32_t alloc_size; + + void Assign(string_t input, AggregateInputData &input_data) { + if (input.IsInlined()) { + value = input; + alloc_size = 0; + } else { + auto len = UnsafeNumericCast(input.GetSize()); + char *ptr; + if (alloc_size >= len) { + ptr = value.GetDataWriteable(); + } else { + alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + ptr = char_ptr_cast(input_data.allocator.Allocate(alloc_size)); + } + memcpy(ptr, input.GetData(), len); + value = string_t(ptr, len); + } + } +}; + +struct FirstStringState : FirstStringStateBase { + static constexpr const char *STATE_NAMES[] = {"value"}; + //! The value is exported with the aggregate's return type - it can be e.g. a VARCHAR, BLOB or BIT value + using STATE_TYPE = OptionalStateType>>>; +}; + +//! State for arbitrary types - the value is stored as a binary sort key, exported as the aggregate's return type. +struct FirstSortKeyState : FirstStringStateBase { + static constexpr const char *STATE_NAMES[] = {"value"}; + using STATE_TYPE = + OptionalStateType>>>; }; struct FirstFunctionBase { @@ -51,11 +100,11 @@ struct FirstFunction : public FirstFunctionBase { if (!unary_input.RowIsValid()) { if (!SKIP_NULLS) { state.is_set = true; + state.value_is_valid = false; } - state.is_null = true; } else { state.is_set = true; - state.is_null = false; + state.value_is_valid = true; state.value = input; } } @@ -79,13 +128,13 @@ struct FirstFunction : public FirstFunctionBase { auto idx = isel.get_index(sel ? sel[k] : k); if (ALL_VALID || validity.RowIsValidUnsafe(idx)) { state.is_set = true; - state.is_null = false; + state.value_is_valid = true; state.value = vals[idx]; return true; } if (!SKIP_NULLS) { state.is_set = true; - state.is_null = true; + state.value_is_valid = false; return true; } return false; @@ -111,7 +160,7 @@ struct FirstFunction : public FirstFunctionBase { template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (!state.is_set || state.is_null) { + if (!state.is_set || !state.value_is_valid) { finalize_data.ReturnNull(); } else { target = state.value; @@ -121,45 +170,24 @@ struct FirstFunction : public FirstFunctionBase { template struct FirstFunctionStringBase : public FirstFunctionBase { - template + template static void SetValue(STATE &state, AggregateInputData &input_data, string_t value, bool is_null) { - if (LAST && state.is_set) { - Destroy(state, input_data); - } if (is_null) { if (!SKIP_NULLS) { state.is_set = true; - state.is_null = true; + state.value_is_valid = false; } } else { state.is_set = true; - state.is_null = false; - if ((COMBINE && !LAST) || value.IsInlined()) { - // We use the aggregate allocator for 'first', so the allocation is already done when combining - // Of course, if the value is inlined, we also don't need to allocate - state.value = value; - } else { - // non-inlined string, need to allocate space for it - auto len = value.GetSize(); - auto ptr = LAST ? new char[len] : char_ptr_cast(input_data.allocator.Allocate(len)); - memcpy(ptr, value.GetData(), len); - - state.value = string_t(ptr, UnsafeNumericCast(len)); - } + state.value_is_valid = true; + state.Assign(value, input_data); } } template static void Combine(const STATE &source, STATE &target, AggregateInputData &input_data) { if (source.is_set && (LAST || !target.is_set)) { - SetValue(target, input_data, source.value, source.is_null); - } - } - - template - static void Destroy(STATE &state, AggregateInputData &) { - if (state.is_set && !state.is_null && !state.value.IsInlined()) { - delete[] state.value.GetData(); + SetValue(target, input_data, source.value, !source.value_is_valid); } } }; @@ -208,7 +236,7 @@ struct FirstFunctionString : FirstFunctionStringBase { template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (!state.is_set || state.is_null) { + if (!state.is_set || !state.value_is_valid) { finalize_data.ReturnNull(); } else { target = StringVector::AddStringOrBlob(finalize_data.result, state.value); @@ -218,7 +246,7 @@ struct FirstFunctionString : FirstFunctionStringBase { template struct FirstVectorFunction : FirstFunctionStringBase { - using STATE = FirstState; + using STATE = FirstSortKeyState; static void Update(Vector inputs[], AggregateInputData &input_data, idx_t, Vector &state_vector, idx_t count) { auto &input = inputs[0]; @@ -278,7 +306,7 @@ struct FirstVectorFunction : FirstFunctionStringBase { template static void Finalize(STATE &state, AggregateFinalizeData &finalize_data) { - if (!state.is_set || state.is_null) { + if (!state.is_set || !state.value_is_valid) { finalize_data.ReturnNull(); } else { CreateSortKeyHelpers::DecodeSortKey(state.value, finalize_data.result, finalize_data.result_idx, @@ -381,21 +409,16 @@ AggregateFunction GetFirstFunction(const LogicalType &type) { case PhysicalType::INTERVAL: return GetFirstAggregateTemplated(type); case PhysicalType::VARCHAR: - if (LAST) { - return AggregateFunction::UnaryAggregateDestructor, string_t, string_t, - FirstFunctionString>(type, type); - } else { - return AggregateFunction::UnaryAggregate, string_t, string_t, - FirstFunctionString>(type, type); - } + return AggregateFunction::UnaryAggregate>(type, type); default: { using OP = FirstVectorFunction; - using STATE = FirstState; + using STATE = FirstSortKeyState; auto fun = AggregateFunction( {type}, type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, OP::Update, AggregateFunction::StateCombine, AggregateFunction::StateVoidFinalize, - FunctionNullHandling::DEFAULT_NULL_HANDLING, AggregateFunction::NoClusterUpdate(), OP::Bind, - LAST ? AggregateFunction::StateDestroy : nullptr, nullptr, nullptr); + FunctionNullHandling::DEFAULT_NULL_HANDLING, AggregateFunction::NoClusterUpdate(), OP::Bind, nullptr, + nullptr, nullptr); AggregateFunction::WireStructStateType(fun); return fun; } diff --git a/src/duckdb/src/function/aggregate/distributive/minmax.cpp b/src/duckdb/src/function/aggregate/distributive/minmax.cpp index 3fa331fc0..83135ccde 100644 --- a/src/duckdb/src/function/aggregate/distributive/minmax.cpp +++ b/src/duckdb/src/function/aggregate/distributive/minmax.cpp @@ -24,7 +24,8 @@ namespace { template struct MinMaxState { using value_type = T; - using STATE_TYPE = OptionalStateType; + //! The value is exported with the aggregate's return type (e.g. DATE or UUID instead of the physical type) + using STATE_TYPE = OptionalStateType>; T value; bool is_set; }; @@ -141,48 +142,41 @@ struct NumericMinMaxBase : public MinMaxBase, public ClusteredStateCopy { using MinOperation = NumericMinMaxBase; using MaxOperation = NumericMinMaxBase; -struct MinMaxStringState { +//! Shared state layout for both MinMaxStringState and MinMaxSortKeyState. +//! Stores a string_t value (regular string or sort key blob) with power-of-two allocation reuse. +struct BaseMinMaxStringState { string_t value; bool is_set; - void Destroy() { - if (is_set && !value.IsInlined()) { - delete[] value.GetData(); - } - } + uint32_t alloc_size; - void Assign(string_t input) { + void Assign(string_t input, AggregateInputData &input_data) { if (input.IsInlined()) { - // inlined string - we can directly store it into the string_t without having to allocate anything - Destroy(); value = input; + alloc_size = 0; } else { - // non-inlined string, need to allocate space for it somehow - auto len = input.GetSize(); + auto len = UnsafeNumericCast(input.GetSize()); char *ptr; - if (!is_set || value.GetSize() < len) { - // we cannot fit this into the current slot - destroy it and re-allocate - Destroy(); - ptr = new char[len]; - } else { - // this fits into the current slot - take over the pointer + if (alloc_size >= len) { ptr = value.GetDataWriteable(); + } else { + alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + ptr = char_ptr_cast(input_data.allocator.Allocate(alloc_size)); } memcpy(ptr, input.GetData(), len); - - value = string_t(ptr, UnsafeNumericCast(len)); + value = string_t(ptr, len); } } }; -struct StringMinMaxBase : public MinMaxBase { - template - static void Destroy(STATE &state, AggregateInputData &aggr_input_data) { - state.Destroy(); - } +struct MinMaxStringState : BaseMinMaxStringState { + //! The value is exported with the aggregate's return type - it can be e.g. a VARCHAR, BLOB or BIT value + using STATE_TYPE = OptionalStateType>; +}; +struct StringMinMaxBase : public MinMaxBase { template static void Assign(STATE &state, INPUT_TYPE input, AggregateInputData &input_data) { - state.Assign(input); + state.Assign(input, input_data); } template @@ -231,14 +225,9 @@ struct VectorMinMaxBase { return true; } - template - static void Destroy(STATE &state, AggregateInputData &aggr_input_data) { - state.Destroy(); - } - template static void Assign(STATE &state, INPUT_TYPE input, AggregateInputData &input_data) { - state.Assign(input); + state.Assign(input, input_data); } template @@ -285,14 +274,21 @@ struct MinOperationVector : VectorMinMaxBase {}; struct MaxOperationVector : VectorMinMaxBase {}; -template +template +struct MinMaxSortKeyState : BaseMinMaxStringState { + using STATE_TYPE = OptionalStateType>; +}; + +template static AggregateFunction GetMinMaxFunction(const LogicalType &type) { - return AggregateFunction( + using STATE = MinMaxSortKeyState; + auto result = AggregateFunction( {type}, LogicalType::BLOB, AggregateFunction::StateSize, AggregateFunction::StateInitialize, AggregateSortKeyHelpers::UnaryUpdate, AggregateFunction::StateCombine, AggregateFunction::StateVoidFinalize, - FunctionNullHandling::DEFAULT_NULL_HANDLING, AggregateFunction::NoClusterUpdate(), OP::Bind, - AggregateFunction::StateDestroy); + FunctionNullHandling::DEFAULT_NULL_HANDLING, AggregateFunction::NoClusterUpdate(), OP::Bind, nullptr); + AggregateFunction::WireStructStateType(result); + return result; } template @@ -300,12 +296,11 @@ static AggregateFunction GetMinMaxOperator(const LogicalType &type) { auto internal_type = type.InternalType(); switch (internal_type) { case PhysicalType::VARCHAR: - return AggregateFunction::UnaryAggregateDestructor(type, - type); + return AggregateFunction::UnaryAggregate(type, type); case PhysicalType::LIST: case PhysicalType::STRUCT: case PhysicalType::ARRAY: - return GetMinMaxFunction(type); + return GetMinMaxFunction(type); default: return GetUnaryAggregate(type); } diff --git a/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp b/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp index 6f586bfd5..ce3c7c106 100644 --- a/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +++ b/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp @@ -2,8 +2,9 @@ #include "duckdb/common/numeric_utils.hpp" #include "duckdb/common/sorting/sort.hpp" #include "duckdb/common/vector/flat_vector.hpp" -#include "duckdb/common/types/column/column_data_collection.hpp" +#include "duckdb/common/vector/struct_vector.hpp" #include "duckdb/common/types/list_segment.hpp" +#include "duckdb/function/aggregate/list_aggregate.hpp" #include "duckdb/function/aggregate_function.hpp" #include "duckdb/function/function_binder.hpp" #include "duckdb/planner/expression/bound_window_expression.hpp" @@ -68,13 +69,14 @@ struct SortedAggregateBindData : public FunctionData { orders.emplace_back(std::move(order)); } - // Look up all the linked list functions we need - for (auto &type : buffered_types) { - ListSegmentFunctions funcs; - GetSegmentDataFunctions(funcs, type); - buffered_funcs.emplace_back(std::move(funcs)); - sort_types.emplace_back(type); + // The buffered rows are stored in a linked list of structs + child_list_t buffered_children; + for (idx_t i = 0; i < buffered_types.size(); i++) { + buffered_children.emplace_back("v" + to_string(i), buffered_types[i]); + sort_types.emplace_back(buffered_types[i]); } + buffered_struct_type = LogicalType::STRUCT(std::move(buffered_children)); + GetSegmentDataFunctions(buffered_funcs, buffered_struct_type); // Only scan the argument columns after sorting sort = make_uniq(context, orders, sort_types, scan_cols); @@ -93,7 +95,8 @@ struct SortedAggregateBindData : public FunctionData { SortedAggregateBindData(const SortedAggregateBindData &other) : context(other.context), function(other.function), sort_types(other.sort_types), scan_cols(other.scan_cols), scan_types(other.scan_types), buffered_cols(other.buffered_cols), buffered_types(other.buffered_types), - buffered_funcs(other.buffered_funcs), sorted_on_args(other.sorted_on_args), threshold(other.threshold) { + buffered_struct_type(other.buffered_struct_type), buffered_funcs(other.buffered_funcs), + sorted_on_args(other.sorted_on_args), threshold(other.threshold) { if (other.bind_info) { bind_info = other.bind_info->Copy(); } @@ -150,8 +153,10 @@ struct SortedAggregateBindData : public FunctionData { vector buffered_cols; //! The schema of the buffered data vector buffered_types; - //! The linked list functions for the buffered data - vector buffered_funcs; + //! The struct type holding one buffered row + LogicalType buffered_struct_type; + //! The linked list functions for the buffered rows + ListSegmentFunctions buffered_funcs; //! Can we just use the inputs for sorting? bool sorted_on_args = true; @@ -159,291 +164,12 @@ struct SortedAggregateBindData : public FunctionData { const idx_t threshold; }; -struct SortedAggregateState { - // Linked list equivalent of DataChunk - using LinkedLists = vector; - using LinkedChunkFunctions = vector; - - //! Capacities of the various levels of buffering - static const idx_t CHUNK_CAPACITY = STANDARD_VECTOR_SIZE; - static const idx_t LIST_CAPACITY = MinValue(16, CHUNK_CAPACITY); - - SortedAggregateState() : count(0), nsel(0), offset(0) { - } - - static inline void InitializeLinkedList(LinkedLists &linked, const vector &types) { - if (linked.empty() && !types.empty()) { - linked.resize(types.size(), LinkedList()); - } - } - - inline void InitializeLinkedLists(const SortedAggregateBindData &order_bind) { - InitializeLinkedList(input_linked, order_bind.buffered_types); - } - - static inline void InitializeChunk(Allocator &allocator, unique_ptr &chunk, - const vector &types) { - if (!chunk && !types.empty()) { - chunk = make_uniq(); - chunk->Initialize(allocator, types); - } - } - - void InitializeChunks(const SortedAggregateBindData &order_bind) { - // Lazy instantiation of the buffer chunks - auto &allocator = BufferManager::GetBufferManager(order_bind.context).GetBufferAllocator(); - InitializeChunk(allocator, input_chunk, order_bind.buffered_types); - } - - static inline void FlushLinkedList(const LinkedChunkFunctions &funcs, LinkedLists &linked, DataChunk &chunk) { - idx_t total_count = 0; - for (column_t i = 0; i < linked.size(); ++i) { - funcs[i].BuildListVector(linked[i], chunk.data[i], total_count); - FlatVector::SetSize(chunk.data[i], count_t(linked[i].total_capacity)); - } - } - - void FlushLinkedLists(const SortedAggregateBindData &order_bind) { - InitializeChunks(order_bind); - FlushLinkedList(order_bind.buffered_funcs, input_linked, *input_chunk); - } - - void InitializeCollections(const SortedAggregateBindData &order_bind) { - input_collection = make_uniq(order_bind.context, order_bind.buffered_types); - input_append = make_uniq(); - input_collection->InitializeAppend(*input_append); - } - - void FlushChunks(const SortedAggregateBindData &order_bind) { - D_ASSERT(input_chunk); - input_collection->Append(*input_append, *input_chunk); - input_chunk->Reset(); - } - - void Resize(const SortedAggregateBindData &order_bind, idx_t n) { - count = n; - - // Establish the current buffering - if (count <= LIST_CAPACITY) { - InitializeLinkedLists(order_bind); - } - - if (count > LIST_CAPACITY && !input_chunk && !input_collection) { - FlushLinkedLists(order_bind); - } - - if (count > CHUNK_CAPACITY && !input_collection) { - InitializeCollections(order_bind); - FlushChunks(order_bind); - } - } - - static void LinkedAppend(const LinkedChunkFunctions &functions, ArenaAllocator &allocator, DataChunk &input, - LinkedLists &linked, SelectionVector &sel, idx_t nsel) { - for (column_t c = 0; c < input.ColumnCount(); ++c) { - auto &func = functions[c]; - auto &linked_list = linked[c]; - RecursiveUnifiedVectorFormat input_data; - Vector::RecursiveToUnifiedFormat(input.data[c], input_data); - for (idx_t i = 0; i < nsel; ++i) { - idx_t sidx = sel.get_index(i); - func.AppendRow(allocator, linked_list, input_data, sidx); - } - } - } - - static void LinkedAbsorb(LinkedLists &source, LinkedLists &target) { - D_ASSERT(source.size() == target.size()); - for (column_t i = 0; i < source.size(); ++i) { - auto &src = source[i]; - if (!src.total_capacity) { - break; - } - - auto &tgt = target[i]; - if (!tgt.total_capacity) { - tgt = src; - } else { - // append the linked list - tgt.last_segment->next = src.first_segment; - tgt.last_segment = src.last_segment; - tgt.total_capacity += src.total_capacity; - } - } - } - - void Update(const AggregateInputData &aggr_input_data, DataChunk &input) { - const auto &order_bind = aggr_input_data.bind_data->Cast(); - Resize(order_bind, count + input.size()); - - sel.Initialize(nullptr); - nsel = input.size(); - - if (input_collection) { - // Using collections - input_collection->Append(*input_append, input); - } else if (input_chunk) { - // Still using data chunks - input_chunk->Append(input); - } else { - // Still using linked lists - LinkedAppend(order_bind.buffered_funcs, aggr_input_data.allocator, input, input_linked, sel, nsel); - } - - nsel = 0; - offset = 0; - } - - void UpdateSlice(const AggregateInputData &aggr_input_data, DataChunk &input) { - const auto &order_bind = aggr_input_data.bind_data->Cast(); - Resize(order_bind, count + nsel); - - if (input_collection) { - // Using collections - D_ASSERT(input_chunk); - input_chunk->Slice(input, sel, nsel); - FlushChunks(order_bind); - } else if (input_chunk) { - // Still using data chunks - input_chunk->Append(input, sel, nsel, VectorAppendMode::ALLOW_RESIZE); - } else { - // Still using linked lists - LinkedAppend(order_bind.buffered_funcs, aggr_input_data.allocator, input, input_linked, sel, nsel); - } - - nsel = 0; - offset = 0; - } - - void Swap(SortedAggregateState &other) { - std::swap(count, other.count); - - std::swap(input_collection, other.input_collection); - std::swap(input_append, other.input_append); - - std::swap(input_chunk, other.input_chunk); - - std::swap(input_linked, other.input_linked); - } - - void Absorb(const SortedAggregateBindData &order_bind, SortedAggregateState &other) { - if (!other.count) { - return; - } else if (!count) { - Swap(other); - return; - } - - // Change to a state large enough for all the data - Resize(order_bind, count + other.count); - - // 3x3 matrix. - // We can simplify the logic a bit because the target is already set for the final capacity - if (!input_chunk) { - // If the combined count is still linked lists, - // then just move the pointers. - // Note that this assumes ArenaAllocator is shared and the memory will not vanish under us. - LinkedAbsorb(other.input_linked, input_linked); - - other.Reset(); - return; - } - - if (!other.input_chunk) { - other.FlushLinkedLists(order_bind); - } - - if (!input_collection) { - // Still using chunks, which means the source is using chunks or lists - D_ASSERT(input_chunk); - D_ASSERT(other.input_chunk); - input_chunk->Append(*other.input_chunk); - } else { - // Using collections, so source could be using anything. - if (other.input_collection) { - input_collection->Combine(*other.input_collection); - } else { - input_collection->Append(*other.input_chunk); - } - } - - // Free all memory as we have absorbed it. - other.Reset(); - } - - void PrefixSortBuffer(DataChunk &prefixed) { - for (column_t col_idx = 0; col_idx < input_chunk->ColumnCount(); ++col_idx) { - prefixed.data[col_idx + 1].Reference(input_chunk->data[col_idx]); - } - // data[0] was referenced as a constant with count=1 - resize to match - FlatVector::SetSize(prefixed.data[0], count_t(input_chunk->size())); - } - - void Finalize(const SortedAggregateBindData &order_bind, DataChunk &prefixed, ExecutionContext &context, - OperatorSinkInput &sink) { - auto &sort = *order_bind.sort; - if (input_collection) { - ColumnDataScanState sort_state; - input_collection->InitializeScan(sort_state); - for (input_chunk->Reset(); input_collection->Scan(sort_state, *input_chunk); input_chunk->Reset()) { - PrefixSortBuffer(prefixed); - sort.Sink(context, prefixed, sink); - } - } else { - // Force chunks so we can sort - if (!input_chunk) { - FlushLinkedLists(order_bind); - } - - PrefixSortBuffer(prefixed); - sort.Sink(context, prefixed, sink); - } - - Reset(); - } - - void Reset() { - // Release all memory - input_collection.reset(); - input_chunk.reset(); - input_linked.clear(); - - count = 0; - } - - idx_t count; - - unique_ptr input_collection; - unique_ptr input_append; - unique_ptr input_chunk; - LinkedLists input_linked; - - // Selection for scattering - SelectionVector sel; - idx_t nsel; - idx_t offset; -}; +//! The sorted aggregate buffers its input rows in a linked list of structs, sharing the "list" callbacks +struct SortedAggregateState : ListAggState {}; struct SortedAggregateFunction { - template - static void Initialize(STATE &state) { - new (&state) STATE(); - } - - template - static void Destroy(STATE &state, AggregateInputData &aggr_input_data) { - state.~STATE(); - } - - static void ProjectInputs(Vector inputs[], const SortedAggregateBindData &order_bind, idx_t input_count, - idx_t count, DataChunk &buffered) { - // Only reference the buffered columns - buffered.InitializeEmpty(order_bind.buffered_types); - const auto &buffered_cols = order_bind.buffered_cols; - for (idx_t b = 0; b < buffered_cols.size(); ++b) { - D_ASSERT(buffered_cols[b] < input_count); - buffered.data[b].Reference(inputs[buffered_cols[b]]); - } + static LogicalType GetElementType(AggregateInputData &aggr_input_data) { + return aggr_input_data.bind_data->Cast().buffered_struct_type; } static void ScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, Vector &states, @@ -451,57 +177,17 @@ struct SortedAggregateFunction { if (!count) { return; } - - // Append the arguments to the two sub-collections + // Pack the buffered columns into a single struct vector for the list update const auto &order_bind = aggr_input_data.bind_data->Cast(); - DataChunk arg_inputs; - ProjectInputs(inputs, order_bind, input_count, count, arg_inputs); - - // We have to scatter the chunks one at a time - // so build a selection vector for each one. - UnifiedVectorFormat svdata; - states.ToUnifiedFormat(svdata); - - // Size the selection vector for each state. - auto sdata = UnifiedVectorFormat::GetData(svdata); - for (idx_t i = 0; i < count; ++i) { - auto sidx = svdata.sel->get_index(i); - auto order_state = sdata[sidx]; - order_state->nsel++; - } - - // Build the selection vector for each state. - vector sel_data(count); - idx_t start = 0; - for (idx_t i = 0; i < count; ++i) { - auto sidx = svdata.sel->get_index(i); - auto order_state = sdata[sidx]; - if (!order_state->offset) { - // First one - order_state->offset = start; - order_state->sel.Initialize(sel_data.data() + order_state->offset, count - order_state->offset); - start += order_state->nsel; - } - sel_data[order_state->offset++] = UnsafeNumericCast(i); - } - - // Append nonempty slices to the arguments - for (idx_t i = 0; i < count; ++i) { - auto sidx = svdata.sel->get_index(i); - auto order_state = sdata[sidx]; - if (!order_state->nsel) { - continue; - } - - order_state->UpdateSlice(aggr_input_data, arg_inputs); + Vector packed(order_bind.buffered_struct_type, count); + auto &entries = StructVector::GetEntries(packed); + const auto &buffered_cols = order_bind.buffered_cols; + for (idx_t b = 0; b < buffered_cols.size(); ++b) { + D_ASSERT(buffered_cols[b] < input_count); + entries[b].Reference(inputs[buffered_cols[b]]); } - } - - template - static void Combine(const STATE &source, STATE &target, AggregateInputData &aggr_input_data) { - auto &order_bind = aggr_input_data.bind_data->Cast(); - auto &other = const_cast(source); // NOLINT: absorb explicitly allows destruction - target.Absorb(order_bind, other); + FlatVector::SetSize(packed, count_t(count)); + ListUpdateFunction(&packed, aggr_input_data, 1, states, count); } static void Window(AggregateInputData &aggr_input_data, const WindowPartitionInput &partition, @@ -518,6 +204,32 @@ struct SortedAggregateFunction { } } + //! Sinks all buffered rows of the state into the sort, prefixed with the group number + static void SinkState(const SortedAggregateBindData &order_bind, SortedAggregateState &state, idx_t group_number, + ExecutionContext &context, OperatorSinkInput &sink, DataChunk &prefixed) { + auto &sort = *order_bind.sort; + ListSegmentScanState scan_state; + order_bind.buffered_funcs.InitializeScan(state.linked_list, scan_state); + for (;;) { + Vector rows(order_bind.buffered_struct_type, STANDARD_VECTOR_SIZE); + const auto chunk_count = order_bind.buffered_funcs.Scan(scan_state, rows); + if (!chunk_count) { + break; + } + auto &entries = StructVector::GetEntries(rows); + prefixed.Reset(); + prefixed.data[0].Reference(Value::USMALLINT(UnsafeNumericCast(group_number)), count_t(1)); + FlatVector::SetSize(prefixed.data[0], count_t(chunk_count)); + for (column_t col_idx = 0; col_idx < entries.size(); ++col_idx) { + prefixed.data[col_idx + 1].Reference(entries[col_idx]); + FlatVector::SetSize(prefixed.data[col_idx + 1], count_t(chunk_count)); + } + sort.Sink(context, prefixed, sink); + } + // Release the state - the rows are freed with the arena allocator + state.linked_list = LinkedList(); + } + static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, const idx_t offset) { auto &order_bind = aggr_input_data.bind_data->Cast(); @@ -549,7 +261,7 @@ struct SortedAggregateFunction { vector state_unprocessed(count, 0); for (idx_t i = 0; i < count; ++i) { - state_unprocessed[i] = sdata[i].GetValueUnsafe()->count; + state_unprocessed[i] = sdata[i].GetValueUnsafe()->linked_list.total_capacity; } ThreadContext thread(client); @@ -568,10 +280,8 @@ struct SortedAggregateFunction { for (idx_t finalized = 0; finalized < count;) { if (unsorted_count < order_bind.threshold) { auto state = sdata[finalized].GetValueUnsafe(); - prefixed.Reset(); - prefixed.data[0].Reference(Value::USMALLINT(UnsafeNumericCast(finalized)), count_t(1)); OperatorSinkInput sink {*global_sink, *local_sink, interrupt}; - state->Finalize(order_bind, prefixed, context, sink); + SinkState(order_bind, *state, finalized, context, sink, prefixed); unsorted_count += state_unprocessed[finalized]; // Go to the next aggregate unless this is the last one @@ -711,16 +421,13 @@ void FunctionBinder::BindSortedAggregate(ClientContext &context, BoundAggregateE } // Replace the aggregate with the wrapper - AggregateFunction ordered_aggregate( - bound_function.GetName(), arguments, bound_function.GetReturnType(), - AggregateFunction::StateSize, - AggregateFunction::StateInitialize, - SortedAggregateFunction::ScatterUpdate, - AggregateFunction::StateCombine, - SortedAggregateFunction::Finalize, bound_function.GetProperties().GetNullHandling(), nullptr, nullptr, - AggregateFunction::StateDestroy, nullptr, - SortedAggregateFunction::WindowBatch); + AggregateFunction ordered_aggregate(bound_function.GetName(), arguments, bound_function.GetReturnType(), + AggregateFunction::StateSize, + AggregateFunction::StateInitialize, + SortedAggregateFunction::ScatterUpdate, + ListCombineFunction, SortedAggregateFunction::Finalize, + bound_function.GetProperties().GetNullHandling(), nullptr, nullptr, nullptr, + nullptr, SortedAggregateFunction::WindowBatch); expr.FunctionMutable().ReplaceImplementation(ordered_aggregate); expr.BindInfoMutable() = std::move(sorted_bind); @@ -770,12 +477,9 @@ void FunctionBinder::BindSortedAggregate(ClientContext &context, BoundWindowExpr // Replace the aggregate with the wrapper AggregateFunction ordered_aggregate( aggregate.GetName(), arguments, aggregate.GetReturnType(), AggregateFunction::StateSize, - AggregateFunction::StateInitialize, - SortedAggregateFunction::ScatterUpdate, - AggregateFunction::StateCombine, - SortedAggregateFunction::Finalize, aggregate.GetProperties().GetNullHandling(), nullptr, nullptr, - AggregateFunction::StateDestroy, nullptr, + AggregateFunction::StateInitialize, SortedAggregateFunction::ScatterUpdate, + ListCombineFunction, SortedAggregateFunction::Finalize, + aggregate.GetProperties().GetNullHandling(), nullptr, nullptr, nullptr, nullptr, SortedAggregateFunction::WindowBatch); ordered_aggregate.SetWindowCallback(SortedAggregateFunction::Window); diff --git a/src/duckdb/src/function/cast/cast_function_set.cpp b/src/duckdb/src/function/cast/cast_function_set.cpp index 5a688f0b3..034edaf8b 100644 --- a/src/duckdb/src/function/cast/cast_function_set.cpp +++ b/src/duckdb/src/function/cast/cast_function_set.cpp @@ -25,7 +25,7 @@ BindCastFunction::BindCastFunction(bind_cast_function_t function_p, unique_ptrAddEntry(source, target, std::move(node)); } +void CastFunctionSet::RegisterCombineTypesRule(CombineTypesRule rule) { + combine_rules.insert(combine_rules.begin(), rule); // newest extension first, ahead of built-ins +} + +bool CastFunctionSet::TryCombineTypes(const vector &rules, LogicalTypeResolver &resolver, + const LogicalType &left, const LogicalType &right, LogicalType &result, + bool &success) { + // first matching rule wins + for (auto &rule : rules) { + if (rule.matches(left, right)) { + success = rule.function(resolver, left, right, result); + return true; + } + } + return false; +} + +bool CastFunctionSet::TryCombineTypes(LogicalTypeResolver &resolver, const LogicalType &left, const LogicalType &right, + LogicalType &result, bool &success) { + return TryCombineTypes(combine_rules, resolver, left, right, result, success); +} + } // namespace duckdb diff --git a/src/duckdb/src/function/combine_types_rules.cpp b/src/duckdb/src/function/combine_types_rules.cpp new file mode 100644 index 000000000..33aa097c1 --- /dev/null +++ b/src/duckdb/src/function/combine_types_rules.cpp @@ -0,0 +1,359 @@ +#include "duckdb/function/combine_types_rule.hpp" +#include "duckdb/common/helper.hpp" +#include "duckdb/common/numeric_utils.hpp" +#include "duckdb/common/insertion_order_preserving_map.hpp" + +namespace duckdb { + +// =========================================== +// ================== ALIASES ================ +// =========================================== +static bool CombineNoAliasTypes(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // we always prefer aliased types + if (!left.GetAlias().empty()) { + result = left; + return true; + } + result = right; + return true; +} + +static bool MatchesNoAlias(const LogicalType &left, const LogicalType &right) { + return !left.GetAlias().empty() || !right.GetAlias().empty(); +} + +// =========================================== +// ================== EQUAL ================== +// =========================================== +static bool CombineStructTypes(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + auto &left_children = StructType::GetChildTypes(left); + auto &right_children = StructType::GetChildTypes(right); + + auto left_unnamed = StructType::IsUnnamed(left); + auto is_unnamed = left_unnamed || StructType::IsUnnamed(right); + child_list_t child_types; + + // At least one side is unnamed, so we attempt positional casting. + if (is_unnamed) { + if (left_children.size() != right_children.size()) { + // We can't cast, or create the super-set. + return false; + } + + for (idx_t i = 0; i < left_children.size(); i++) { + LogicalType child_type; + if (!logical_type_resolver.Operation(left_children[i].second, right_children[i].second, child_type)) { + return false; + } + auto &child_name = left_unnamed ? right_children[i].first : left_children[i].first; + child_types.emplace_back(child_name, std::move(child_type)); + } + result = LogicalType::STRUCT(child_types); + return true; + } + + // Create a super-set of the STRUCT fields. + // First, create a name->index map of the right children. + InsertionOrderPreservingMap> right_children_map; + for (idx_t i = 0; i < right_children.size(); i++) { + auto &name = right_children[i].first; + right_children_map[name] = i; + } + + for (idx_t i = 0; i < left_children.size(); i++) { + auto &left_child = left_children[i]; + auto right_child_it = right_children_map.find(left_child.first); + + if (right_child_it == right_children_map.end()) { + // We can directly put the left child. + child_types.emplace_back(left_child.first, left_child.second); + continue; + } + + // We need to recurse to ensure the children have a maximum logical type. + LogicalType child_type; + auto &right_child = right_children[right_child_it->second]; + if (!logical_type_resolver.Operation(left_child.second, right_child.second, child_type)) { + return false; + } + child_types.emplace_back(left_child.first, std::move(child_type)); + right_children_map.erase(right_child_it); + } + + // Add all remaining right children. + for (const auto &right_child_it : right_children_map) { + auto &right_child = right_children[right_child_it.second]; + child_types.emplace_back(right_child.first, right_child.second); + } + + result = LogicalType::STRUCT(child_types); + return true; +} + +static bool CombineEqualStringLiteral(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + result = LogicalType::VARCHAR; + return true; +} +static bool CombineEqualIntegerLiteral(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // for two integer literals we unify the underlying types + return logical_type_resolver.Operation(IntegerLiteral::GetType(left), IntegerLiteral::GetType(right), result); +} +static bool CombineEqualEnum(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // If both types are different ENUMs we do a string comparison. + result = left == right ? left : LogicalType::VARCHAR; + return true; +} +static bool CombineEqualVarchar(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // varchar: use type that has collation (if any) + if (StringType::GetCollation(right).empty()) { + result = left; + } else { + result = right; + } + return true; +} +static bool CombineEqualDecimal(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // unify the width/scale so that the resulting decimal always fits + // "width - scale" gives us the number of digits on the left side of the decimal point + // "scale" gives us the number of digits allowed on the right of the decimal point + // using the max of these of the two types gives us the new decimal size + auto extra_width_left = DecimalType::GetWidth(left) - DecimalType::GetScale(left); + auto extra_width_right = DecimalType::GetWidth(right) - DecimalType::GetScale(right); + auto extra_width = + MaxValue(NumericCast(extra_width_left), NumericCast(extra_width_right)); + auto scale = MaxValue(DecimalType::GetScale(left), DecimalType::GetScale(right)); + auto width = NumericCast(extra_width + scale); + if (width > DecimalType::MaxWidth()) { + // if the resulting decimal does not fit, we truncate the scale + width = DecimalType::MaxWidth(); + scale = NumericCast(width - extra_width); + } + result = LogicalType::DECIMAL(width, scale); + return true; +} +static bool CombineEqualList(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // list: perform max recursively on child type + LogicalType new_child; + if (!logical_type_resolver.Operation(ListType::GetChildType(left), ListType::GetChildType(right), new_child)) { + return false; + } + result = LogicalType::LIST(new_child); + return true; +} +static bool CombineEqualArray(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + LogicalType new_child; + if (!logical_type_resolver.Operation(ArrayType::GetChildType(left), ArrayType::GetChildType(right), new_child)) { + return false; + } + auto new_size = MaxValue(ArrayType::GetSize(left), ArrayType::GetSize(right)); + result = LogicalType::ARRAY(new_child, new_size); + return true; +} +static bool CombineEqualMap(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + // map: perform max recursively on child type + LogicalType new_child; + if (!logical_type_resolver.Operation(ListType::GetChildType(left), ListType::GetChildType(right), new_child)) { + return false; + } + result = LogicalType::MAP(new_child); + return true; +} +static bool CombineEqualUnion(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result) { + auto left_member_count = UnionType::GetMemberCount(left); + auto right_member_count = UnionType::GetMemberCount(right); + if (left_member_count != right_member_count) { + // return the "larger" type, with the most members + result = left_member_count > right_member_count ? left : right; + return true; + } + // otherwise, keep left, don't try to meld the two together. + result = left; + return true; +} + +static bool EqualMatchesStringLiteral(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::STRING_LITERAL; +} + +static bool EqualMatchesIntegerLiteral(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::INTEGER_LITERAL; +} + +static bool EqualMatchesEnum(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::ENUM; +} + +static bool EqualMatchesVarchar(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::VARCHAR; +} + +static bool EqualMatchesDecimal(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::DECIMAL; +} + +static bool EqualMatchesList(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::LIST; +} + +static bool EqualMatchesArray(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::ARRAY; +} + +static bool EqualMatchesMap(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::MAP; +} + +static bool EqualMatchesStruct(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::STRUCT; +} + +static bool EqualMatchesUnion(const LogicalType &left, const LogicalType &right) { + if (left.id() != right.id()) { + // rule only applies to equal types + return false; + } + return left.id() == LogicalTypeId::UNION; +} + +// =========================================== +// ================== UNEQUAL ================ +// =========================================== + +static bool CombineNullOrUnknown(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, + LogicalType &result) { + // NULL/unknown (parameter) types always take the other type + if (left.id() == LogicalTypeId::SQLNULL || right.id() == LogicalTypeId::SQLNULL) { + result = LogicalType::NormalizeType(left.id() == LogicalTypeId::SQLNULL ? right : left); + } else { + result = LogicalType::NormalizeType(left.id() == LogicalTypeId::UNKNOWN ? right : left); + } + return true; +} + +static bool CombineEnum(LogicalTypeResolver &logical_type_resolver, const LogicalType &left, const LogicalType &right, + LogicalType &result) { + // for enums, match the varchar rules + if (left.id() == LogicalTypeId::ENUM) { + return logical_type_resolver.Operation(LogicalType::VARCHAR, right, result); + } + return logical_type_resolver.Operation(left, LogicalType::VARCHAR, result); +} + +static bool CombineVariant(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, + LogicalType &result) { + result = right.id() == LogicalTypeId::VARIANT ? right : left; + return true; +} + +// for everything but enums - string literals also take the other type +static bool CombineStringLiteral(LogicalTypeResolver &, const LogicalType &left, const LogicalType &right, + LogicalType &result) { + result = LogicalType::NormalizeType(left.id() == LogicalTypeId::STRING_LITERAL ? right : left); + return true; +} + +static bool UnequalMatchesVariant(const LogicalType &left, const LogicalType &right) { + if (left.id() == right.id()) { + // rule only applies to unequal types + return false; + } + return left.id() == LogicalTypeId::VARIANT || right.id() == LogicalTypeId::VARIANT; +} + +static bool UnequalMatchesNullOrUnknown(const LogicalType &left, const LogicalType &right) { + if (left.id() == right.id()) { + // rule only applies to unequal types + return false; + } + auto null_or_unknown = [](const LogicalType &type) { + return type.id() == LogicalTypeId::SQLNULL || type.id() == LogicalTypeId::UNKNOWN; + }; + return null_or_unknown(left) || null_or_unknown(right); +} + +static bool UnequalMatchesEnum(const LogicalType &left, const LogicalType &right) { + if (left.id() == right.id()) { + // rule only applies to unequal types + return false; + } + return left.id() == LogicalTypeId::ENUM || right.id() == LogicalTypeId::ENUM; +} + +static bool UnequalMatchesStringLiteral(const LogicalType &left, const LogicalType &right) { + if (left.id() == right.id()) { + // rule only applies to unequal types + return false; + } + return left.id() == LogicalTypeId::STRING_LITERAL || right.id() == LogicalTypeId::STRING_LITERAL; +} + +// Rules are matched in order, so the first matching rule wins +const vector &DefaultCombineTypesRules() { + static const vector rules = { + {MatchesNoAlias, CombineNoAliasTypes}, + {UnequalMatchesVariant, CombineVariant}, + {UnequalMatchesNullOrUnknown, CombineNullOrUnknown}, + {UnequalMatchesEnum, CombineEnum}, + {UnequalMatchesStringLiteral, CombineStringLiteral}, + {EqualMatchesStringLiteral, CombineEqualStringLiteral}, + {EqualMatchesIntegerLiteral, CombineEqualIntegerLiteral}, + {EqualMatchesEnum, CombineEqualEnum}, + {EqualMatchesVarchar, CombineEqualVarchar}, + {EqualMatchesDecimal, CombineEqualDecimal}, + {EqualMatchesList, CombineEqualList}, + {EqualMatchesArray, CombineEqualArray}, + {EqualMatchesMap, CombineEqualMap}, + {EqualMatchesStruct, CombineStructTypes}, + {EqualMatchesUnion, CombineEqualUnion}, + }; + return rules; +} + +} // namespace duckdb diff --git a/src/duckdb/src/function/copy_function.cpp b/src/duckdb/src/function/copy_function.cpp index 8f9b997e1..cadc2d7eb 100644 --- a/src/duckdb/src/function/copy_function.cpp +++ b/src/duckdb/src/function/copy_function.cpp @@ -25,7 +25,8 @@ vector GetCopyFunctionReturnNames(CopyFunctionReturnType return_type case CopyFunctionReturnType::CHANGED_ROWS_AND_FILE_LIST: return {"Count", "Files"}; case CopyFunctionReturnType::WRITTEN_FILE_STATISTICS: - return {"filename", "count", "file_size_bytes", "footer_size_bytes", "column_statistics", "partition_keys"}; + return {"filename", "count", "file_size_bytes", "footer_size_bytes", + "column_statistics", "partition_keys", "extra_info"}; default: throw NotImplementedException("Unknown CopyFunctionReturnType"); } @@ -49,7 +50,9 @@ vector GetCopyFunctionReturnLogicalTypes(CopyFunctionReturnType ret //! column_path (potentially nested) -> map(stats_type -> value) LogicalType::MAP(LogicalType::VARCHAR, LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR)), //! partition key -> value - LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR)}; + LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR), + //! format-specific extra info (e.g. row_group_count) + LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARIANT())}; default: throw NotImplementedException("Unknown CopyFunctionReturnType"); } diff --git a/src/duckdb/src/function/function_list.cpp b/src/duckdb/src/function/function_list.cpp index 5dfa42e7d..068cbf201 100644 --- a/src/duckdb/src/function/function_list.cpp +++ b/src/duckdb/src/function/function_list.cpp @@ -159,6 +159,7 @@ static const StaticFunctionDefinition function[] = { DUCKDB_SCALAR_FUNCTION(CurrentQueryId), DUCKDB_SCALAR_FUNCTION(CurrentTransactionId), DUCKDB_SCALAR_FUNCTION(CurrvalFun), + DUCKDB_AGGREGATE_FUNCTION_SET(DecimalAverageFun), DUCKDB_SCALAR_FUNCTION_SET(DecimalDivisionFun), DUCKDB_WINDOW_FUNCTION(DenseRankFun), DUCKDB_SCALAR_FUNCTION_SET_ALIAS(DivideFun), @@ -261,6 +262,7 @@ static const StaticFunctionDefinition function[] = { DUCKDB_SCALAR_FUNCTION_SET(TryStrpTimeFun), DUCKDB_SCALAR_FUNCTION_ALIAS(UcaseFun), DUCKDB_SCALAR_FUNCTION(UpperFun), + DUCKDB_SCALAR_FUNCTION_SET(VariantArrayLengthFun), DUCKDB_SCALAR_FUNCTION_SET(VariantExistsFun), DUCKDB_SCALAR_FUNCTION_SET(VariantExtractFun), DUCKDB_SCALAR_FUNCTION_SET(VariantKeysFun), diff --git a/src/duckdb/src/function/pragma/pragma_functions.cpp b/src/duckdb/src/function/pragma/pragma_functions.cpp index 163e1a29d..f8ddf4d3b 100644 --- a/src/duckdb/src/function/pragma/pragma_functions.cpp +++ b/src/duckdb/src/function/pragma/pragma_functions.cpp @@ -22,7 +22,6 @@ namespace duckdb { static void PragmaEnableProfilingStatement(ClientContext &context, const FunctionParameters ¶meters) { auto &config = ClientConfig::GetConfig(context); config.enable_profiler = true; - config.emit_profiler_output = true; } void RegisterEnableProfiling(BuiltinFunctions &set) { diff --git a/src/duckdb/src/function/scalar/system/aggregate_export.cpp b/src/duckdb/src/function/scalar/system/aggregate_export.cpp index c83510905..6f5e63711 100644 --- a/src/duckdb/src/function/scalar/system/aggregate_export.cpp +++ b/src/duckdb/src/function/scalar/system/aggregate_export.cpp @@ -1,6 +1,9 @@ #include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/common/vector/list_vector.hpp" #include "duckdb/common/vector/struct_vector.hpp" +#include "duckdb/common/types/list_segment.hpp" #include "duckdb/function/aggregate_state_layout.hpp" +#include "duckdb/function/create_sort_key.hpp" #include "duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp" #include "duckdb/common/extension_type_info.hpp" #include "duckdb/common/types/value.hpp" @@ -137,122 +140,152 @@ struct StoreOp { } }; -// Serialize an OptionalStateType state buffer (flat: T value at +0, bool is_set at +sizeof(T)) -// into a result vector, setting NULL when is_set=false. -struct StorePrimitiveOptionalOp { - template - static void Operation(Vector &result, idx_t count, const data_ptr_t *addresses, idx_t base_offset) { - auto dst = FlatVector::Writer(result, count); +// Recursively serialize a state field to a result vector. +// base: accumulated byte offset from the state slot start to this field's parent base. +// Each child's field_offset is relative to that parent base. +static void SerializeField(const LogicalType &type, const AggregateStateField &field, Vector &result, idx_t count, + const data_ptr_t *addresses, idx_t base) { + switch (field.kind) { + case AggregateFieldKind::OPTIONAL_VALUE: + D_ASSERT(field.children.size() == 1); for (idx_t i = 0; i < count; i++) { - const auto value = Load(addresses[i] + base_offset); - const bool is_set = Load(addresses[i] + base_offset + sizeof(T)); - if (is_set) { - dst.WriteValue(value); - } else { - dst.WriteNull(); + if (!Load(addresses[i] + base + field.field_offset)) { + FlatVector::SetNull(result, i, true); } } - } -}; - -// Deserialize a nullable input vector into OptionalStateType state buffer slots -// (flat: T value at +0, bool is_set at +sizeof(T)). -struct LoadPrimitiveOptionalOp { - template - static void Operation(const Vector &input, idx_t count, data_ptr_t base_ptr, idx_t aligned_state_size) { - auto values = input.Values(); + SerializeField(type, field.children[0], result, count, addresses, base); + break; + case AggregateFieldKind::SORT_KEY: for (idx_t i = 0; i < count; i++) { - const auto entry = values[i]; - auto *value_ptr = reinterpret_cast(base_ptr + i * aligned_state_size); - auto *is_set_ptr = reinterpret_cast(base_ptr + i * aligned_state_size + sizeof(T)); - if (entry.IsValid()) { - *value_ptr = entry.GetValue(); - *is_set_ptr = true; - } else { - *is_set_ptr = false; + if (!FlatVector::Validity(result).RowIsValid(i)) { + continue; } + const string_t sort_key = Load(addresses[i] + base + field.field_offset); + CreateSortKeyHelpers::DecodeSortKey(sort_key, result, i, + OrderModifiers(field.sort_key_order, OrderByNullType::NULLS_LAST)); } - } -}; - -void DeserializeState(const AggregateStateLayout &layout, const Vector &input_vec, idx_t count, - data_ptr_t dest_buffer) { - if (layout.field.is_optional && layout.type.id() == LogicalTypeId::STRUCT) { - // Optional struct: deserialize children, then derive is_set from the struct's row validity. - const idx_t struct_size = AggregateStateField::GetPhysicalSize(layout.type); - const auto &child_types = StructType::GetChildTypes(layout.type); - const auto &struct_entries = StructVector::GetEntries(input_vec); - for (idx_t field_idx = 0; field_idx < layout.field.children.size(); field_idx++) { - const auto &child = layout.field.children[field_idx]; - AggregateStateLayout child_layout(child_types[field_idx].second, layout.total_state_size, - child.is_optional); - DeserializeState(child_layout, struct_entries[field_idx], count, dest_buffer + child.field_offset); + break; + case AggregateFieldKind::STRUCT: { + const auto &child_types = StructType::GetChildTypes(type); + auto &struct_entries = StructVector::GetEntries(result); + const idx_t new_base = base + field.field_offset; + for (idx_t field_idx = 0; field_idx < field.children.size(); field_idx++) { + SerializeField(child_types[field_idx].second, field.children[field_idx], struct_entries[field_idx], count, + addresses, new_base); } - auto &validity = FlatVector::Validity(input_vec); + break; + } + case AggregateFieldKind::PRIMITIVE: + TemplateDispatch(type.InternalType(), result, count, addresses, base + field.field_offset); + break; + case AggregateFieldKind::LIST: { + // linked list field: build the result LIST vector from each state's linked list + // an empty linked list is exported as NULL, matching the finalize semantics of list aggregates + D_ASSERT(type.id() == LogicalTypeId::LIST); + vector linked_lists; + linked_lists.reserve(count); for (idx_t i = 0; i < count; i++) { - *reinterpret_cast(dest_buffer + i * layout.total_state_size + struct_size) = validity.RowIsValid(i); - } - } else if (layout.type.id() == LogicalTypeId::STRUCT) { - const auto &child_types = StructType::GetChildTypes(layout.type); - const auto &struct_entries = StructVector::GetEntries(input_vec); - for (idx_t field_idx = 0; field_idx < layout.field.children.size(); field_idx++) { - const auto &child = layout.field.children[field_idx]; - AggregateStateLayout child_layout(child_types[field_idx].second, layout.total_state_size, - child.is_optional); - DeserializeState(child_layout, struct_entries[field_idx], count, dest_buffer + child.field_offset); + linked_lists.push_back(Load(addresses[i] + base + field.field_offset)); } - } else if (layout.field.is_optional) { - TemplateDispatch(layout.type.InternalType(), input_vec, count, dest_buffer, - layout.total_state_size); - } else { - TemplateDispatch(layout.type.InternalType(), layout.total_state_size, input_vec, count, dest_buffer, 0); + field.list_functions.BuildLists(linked_lists, result, 0); + break; + } } } -void SerializeState(const AggregateStateLayout &layout, Vector &result, idx_t count, const data_ptr_t *addresses, - idx_t base_offset = 0) { - if (layout.field.is_optional && layout.type.id() == LogicalTypeId::STRUCT) { - // Optional struct: mark null rows in the struct's validity, then serialize children for all rows. - const idx_t struct_size = AggregateStateField::GetPhysicalSize(layout.type); - const auto &child_types = StructType::GetChildTypes(layout.type); - auto &struct_entries = StructVector::GetEntries(result); +// Recursively deserialize an input vector into a packed state buffer. +// base: accumulated byte offset within each state slot for this field's parent base. +static void DeserializeField(const LogicalType &type, const AggregateStateField &field, const Vector &input_vec, + idx_t count, data_ptr_t dest_buffer, idx_t stride, idx_t base, ArenaAllocator &allocator) { + switch (field.kind) { + case AggregateFieldKind::OPTIONAL_VALUE: { + D_ASSERT(field.children.size() == 1); + const auto validity = input_vec.Validity(); for (idx_t i = 0; i < count; i++) { - if (!Load(addresses[i] + base_offset + struct_size)) { - FlatVector::SetNull(result, i, true); + Store(validity.IsValid(i), dest_buffer + i * stride + base + field.field_offset); + } + DeserializeField(type, field.children[0], input_vec, count, dest_buffer, stride, base, allocator); + break; + } + case AggregateFieldKind::SORT_KEY: { + Vector sort_keys(LogicalType::BLOB); + CreateSortKeyHelpers::CreateSortKey( + input_vec, count, OrderModifiers(field.sort_key_order, OrderByNullType::NULLS_LAST), sort_keys); + auto *key_data = FlatVector::GetData(sort_keys); + const auto validity = input_vec.Validity(); + for (idx_t i = 0; i < count; i++) { + if (!validity.IsValid(i)) { + continue; } + auto sort_key = key_data[i]; + if (!sort_key.IsInlined()) { + const auto len = sort_key.GetSize(); + auto *buf = char_ptr_cast(allocator.Allocate(len)); + memcpy(buf, sort_key.GetData(), len); + sort_key = string_t(buf, UnsafeNumericCast(len)); + } + Store(sort_key, dest_buffer + i * stride + base + field.field_offset); } - for (idx_t field_idx = 0; field_idx < layout.field.children.size(); field_idx++) { - const auto &child = layout.field.children[field_idx]; - AggregateStateLayout child_layout(child_types[field_idx].second, 0, child.is_optional); - SerializeState(child_layout, struct_entries[field_idx], count, addresses, base_offset + child.field_offset); + break; + } + case AggregateFieldKind::STRUCT: { + const auto &child_types = StructType::GetChildTypes(type); + const auto &struct_entries = StructVector::GetEntries(input_vec); + const idx_t new_base = base + field.field_offset; + for (idx_t field_idx = 0; field_idx < field.children.size(); field_idx++) { + DeserializeField(child_types[field_idx].second, field.children[field_idx], struct_entries[field_idx], count, + dest_buffer, stride, new_base, allocator); } - } else if (layout.type.id() == LogicalTypeId::STRUCT) { - const auto &child_types = StructType::GetChildTypes(layout.type); - auto &struct_entries = StructVector::GetEntries(result); - for (idx_t field_idx = 0; field_idx < layout.field.children.size(); field_idx++) { - const auto &child = layout.field.children[field_idx]; - AggregateStateLayout child_layout(child_types[field_idx].second, 0, child.is_optional); - SerializeState(child_layout, struct_entries[field_idx], count, addresses, base_offset + child.field_offset); + break; + } + case AggregateFieldKind::PRIMITIVE: + TemplateDispatch(type.InternalType(), stride, input_vec, count, dest_buffer, base + field.field_offset); + break; + case AggregateFieldKind::LIST: { + // linked list field: append each row of the input LIST vector into the state's linked list + D_ASSERT(type.id() == LogicalTypeId::LIST); + // the child data is appended through the ListSegmentFunctions API, which takes a RecursiveUnifiedVectorFormat + RecursiveUnifiedVectorFormat child_data; + Vector::RecursiveToUnifiedFormat(ListVector::GetChild(input_vec), child_data); + + auto values = input_vec.Values(); + for (idx_t i = 0; i < count; i++) { + LinkedList linked_list; + const auto entry = values[i]; + if (entry.IsValid()) { + // NULL inputs keep an empty linked list + field.list_functions.AppendListEntry(allocator, linked_list, child_data, entry.GetValue()); + } + Store(linked_list, dest_buffer + i * stride + base + field.field_offset); } - } else if (layout.field.is_optional) { - TemplateDispatch(layout.type.InternalType(), result, count, addresses, base_offset); - } else { - TemplateDispatch(layout.type.InternalType(), result, count, addresses, base_offset); + break; } + } +} + +static void DeserializeState(const AggregateStateLayout &layout, const Vector &input_vec, idx_t count, + data_ptr_t dest_buffer, ArenaAllocator &allocator) { + DeserializeField(layout.type, layout.field, input_vec, count, dest_buffer, layout.total_state_size, 0, allocator); +} + +static void SerializeState(const AggregateStateLayout &layout, Vector &result, idx_t count, + const data_ptr_t *addresses) { + SerializeField(layout.type, layout.field, result, count, addresses, 0); } struct CombineState : public FunctionLocalState { - idx_t state_size; + //! The state layout, including the segment functions when the state is a linked list + AggregateStateLayout layout; unsafe_unique_array state_buffer0, state_buffer1; Vector addresses0, addresses1; ArenaAllocator allocator; - explicit CombineState(idx_t state_size_p) - : state_size(state_size_p), - state_buffer0(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * AlignValue(state_size_p))), - state_buffer1(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * AlignValue(state_size_p))), + explicit CombineState(const ExportAggregateBindData &bind_data) + : layout(GetLayout(bind_data.aggr)), + state_buffer0(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * layout.total_state_size)), + state_buffer1(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * layout.total_state_size)), addresses0(LogicalType::POINTER), addresses1(LogicalType::POINTER), allocator(Allocator::DefaultAllocator()) { } }; @@ -260,19 +293,21 @@ struct CombineState : public FunctionLocalState { unique_ptr InitCombineState(ExpressionState &state, const BoundFunctionExpression &expr, FunctionData *bind_data_p) { auto &bind_data = bind_data_p->Cast(); - return make_uniq(bind_data.state_size); + return make_uniq(bind_data); } struct FinalizeState : public FunctionLocalState { - idx_t state_size; + //! The state layout, including the segment functions when the state is a linked list + AggregateStateLayout layout; + unsafe_unique_array state_buffer; Vector addresses; ArenaAllocator allocator; - explicit FinalizeState(idx_t state_size_p) - : state_size(state_size_p), - state_buffer(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * AlignValue(state_size_p))), + explicit FinalizeState(const ExportAggregateBindData &bind_data) + : layout(GetLayout(bind_data.aggr)), + state_buffer(make_unsafe_uniq_array(STANDARD_VECTOR_SIZE * layout.total_state_size)), addresses(LogicalType::POINTER), allocator(Allocator::DefaultAllocator()) { } }; @@ -280,7 +315,7 @@ struct FinalizeState : public FunctionLocalState { unique_ptr InitFinalizeState(ExpressionState &state, const BoundFunctionExpression &expr, FunctionData *bind_data_p) { auto &bind_data = bind_data_p->Cast(); - return make_uniq(bind_data.state_size); + return make_uniq(bind_data); } void AggregateStateFinalize(DataChunk &input, ExpressionState &state_p, Vector &result) { @@ -291,7 +326,7 @@ void AggregateStateFinalize(DataChunk &input, ExpressionState &state_p, Vector & D_ASSERT(bind_data.state_size == bind_data.aggr.GetStateSizeCallback()(bind_data.aggr)); D_ASSERT(input.data.size() == 1); - auto layout = GetLayout(bind_data.aggr); + auto &layout = local_state.layout; auto count = input.size(); auto state_vec_writer = FlatVector::Writer(local_state.addresses, count); @@ -299,7 +334,7 @@ void AggregateStateFinalize(DataChunk &input, ExpressionState &state_p, Vector & state_vec_writer.WriteValue(local_state.state_buffer.get() + i * layout.total_state_size); } - DeserializeState(layout, input.data[0], count, local_state.state_buffer.get()); + DeserializeState(layout, input.data[0], count, local_state.state_buffer.get(), local_state.allocator); AggregateInputData aggr_input_data(bind_data.aggr, bind_data.bind_data.get(), local_state.allocator); bind_data.aggr.GetStateFinalizeCallback()(local_state.addresses, aggr_input_data, result, count, 0); @@ -326,7 +361,7 @@ void AggregateStateCombine(DataChunk &input, ExpressionState &state_p, Vector &r input.data[0].GetType().ToString(), input.data[1].GetType().ToString()); } - auto layout = GetLayout(bind_data.aggr); + auto &layout = local_state.layout; auto count = input.size(); result.Flatten(); @@ -347,8 +382,8 @@ void AggregateStateCombine(DataChunk &input, ExpressionState &state_p, Vector &r } // Deserialize both inputs — null rows are skipped by LoadOp, keeping the initialized empty state - DeserializeState(layout, input.data[0], count, local_state.state_buffer0.get()); - DeserializeState(layout, input.data[1], count, local_state.state_buffer1.get()); + DeserializeState(layout, input.data[0], count, local_state.state_buffer0.get(), local_state.allocator); + DeserializeState(layout, input.data[1], count, local_state.state_buffer1.get(), local_state.allocator); AggregateInputData aggr_input_data(bind_data.aggr, bind_data.bind_data.get(), local_state.allocator, AggregateCombineType::ALLOW_DESTRUCTIVE); @@ -475,6 +510,15 @@ void ExportAggregateFinalize(Vector &state, AggregateInputData &aggr_input_data, SerializeState(layout, result, count, addresses_ptrs); } +// the executor invokes this callback with combine_aggr's own bind data (ExportAggregateBindData) - the underlying +// aggregate's combine expects its own bind data, so we forward it here +void CombineAggrStateCombine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) { + auto &bind_data = aggr_input_data.bind_data->Cast(); + AggregateInputData combine_input(bind_data.aggr, bind_data.bind_data.get(), aggr_input_data.allocator, + aggr_input_data.combine_type); + bind_data.aggr.GetStateCombineCallback()(source, target, combine_input, count); +} + unique_ptr CombineAggrBind(BindAggregateFunctionInput &input) { auto &context = input.GetClientContext(); auto &function = input.GetBoundFunction(); @@ -485,7 +529,7 @@ unique_ptr CombineAggrBind(BindAggregateFunctionInput &input) { // Copy underlying aggregate's callbacks into this function (same pattern as `ExportAggregateFunction::Bind`) function.SetStateSizeCallback(bind_data->aggr.GetStateSizeCallback()); function.SetStateInitCallback(bind_data->aggr.GetStateInitCallback()); - function.SetStateCombineCallback(bind_data->aggr.GetStateCombineCallback()); + function.SetStateCombineCallback(CombineAggrStateCombine); function.SetReturnType(arguments[0]->GetReturnType()); @@ -522,10 +566,9 @@ void CombineAggrUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx target_data.WriteValue(state_values[i].GetValue()); } - DeserializeState(layout, inputs[0], count, temp_state_buf.get()); + DeserializeState(layout, inputs[0], count, temp_state_buf.get(), aggr_input_data.allocator); - ArenaAllocator allocator(Allocator::DefaultAllocator()); - AggregateInputData combine_input(bind_data.aggr, bind_data.bind_data.get(), allocator, + AggregateInputData combine_input(bind_data.aggr, bind_data.bind_data.get(), aggr_input_data.allocator, AggregateCombineType::ALLOW_DESTRUCTIVE); underlying_aggr.GetStateCombineCallback()(source_vec, target_vec, combine_input, count); } @@ -555,7 +598,9 @@ void CombineAggrFinalize(Vector &state, AggregateInputData &aggr_input_data, Vec // the state layout (a struct) is aliased to AGGREGATE_STATE, with the function name and signature stored in the // extension type info so that the aggregate can be re-bound later (e.g. by FINALIZE/COMBINE) LogicalType CreateAggregateStateType(const BoundAggregateFunction &bound_function) { - LogicalType state_layout = bound_function.GetStateType().type; + // deep copy the type before modifying it - SetAlias/SetExtensionInfo modify the (shared) extra type info in + // place, and the state layout type can share its type info with e.g. the aggregate's input expressions + LogicalType state_layout = bound_function.GetStateType().type.DeepCopy(); state_layout.SetAlias("AGGREGATE_STATE"); auto ext_info = make_uniq(); ext_info->properties.emplace("function_name", bound_function.GetName()); diff --git a/src/duckdb/src/function/scalar/variant/variant_array_length.cpp b/src/duckdb/src/function/scalar/variant/variant_array_length.cpp new file mode 100644 index 000000000..e25d226b1 --- /dev/null +++ b/src/duckdb/src/function/scalar/variant/variant_array_length.cpp @@ -0,0 +1,91 @@ +#include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/common/types/variant.hpp" +#include "duckdb/function/scalar/variant_path_function.hpp" +#include "duckdb/function/scalar/variant_functions.hpp" + +namespace duckdb { + +static void WriteArrayLengths(Vector &array_lengths, const array_ptr &nested_data, + const ValidityMask &array_validity, const idx_t count) { + auto writer = FlatVector::Writer(array_lengths, count); + const auto &array_lengths_validity = FlatVector::Validity(array_lengths); + + for (idx_t row_idx = 0; row_idx < count; row_idx++) { + if (!array_lengths_validity.RowIsValid(row_idx)) { + writer.WriteNull(); + continue; + } + if (!array_validity.RowIsValid(row_idx)) { + writer.WriteValue(0); + continue; + } + + const auto &[child_count, children_idx] = nested_data[row_idx]; + writer.WriteValue(child_count); + } +} + +static Vector CollectVariantArrayLengths(const UnifiedVariantVectorData &variant, + const vector &components, const idx_t count) { + Vector array_lengths(LogicalType::UBIGINT, count); + VariantPathSelection path_selection(count); + + const auto owned_nested_data = make_unsafe_uniq_array_uninitialized(count); + const array_ptr nested_data(owned_nested_data.get(), count); + + auto &path_validity = FlatVector::ValidityMutable(array_lengths); + VariantUtils::TraversePath(variant, components, count, nested_data, path_validity, path_selection); + + // For the final collection of nested_data we use an auxiliary validity vector so we can distinguish "path missing" + // from "path exists but not an array" (producing NULL and 0 as output respectively). + ValidityMask array_validity(count); + for (idx_t row_idx = 0; row_idx < count; row_idx++) { + if (!path_validity.RowIsValid(row_idx)) { + array_validity.SetInvalid(row_idx); + } + } + + const auto &final_indices = path_selection.Input(components.size()); + (void)VariantUtils::CollectNestedData(variant, VariantLogicalType::ARRAY, final_indices, count, optional_idx(), 0, + nested_data, array_validity); + + WriteArrayLengths(array_lengths, nested_data, array_validity, count); + + return array_lengths; +} + +static void WriteArrayLengthsResult(const UnifiedVariantVectorData &, VectorWriter &lengths_writer, + const Vector &array_lengths, const idx_t row_idx) { + const auto &array_lengths_validity = FlatVector::Validity(array_lengths); + const auto array_lengths_data = FlatVector::GetData(array_lengths); + + if (!array_lengths_validity.RowIsValid(row_idx)) { + lengths_writer.WriteNull(); + return; + } + + const auto array_length = array_lengths_data[row_idx]; + lengths_writer.WriteValue(array_length); +} + +static void VariantArrayLengthFunction(DataChunk &input, ExpressionState &state, Vector &result) { + VariantPathFunction::Execute(input, state, result, CollectVariantArrayLengths, + WriteArrayLengthsResult); +} + +ScalarFunctionSet VariantArrayLengthFun::GetFunctions() { + ScalarFunctionSet fun_set; + + ScalarFunction variant_exists("variant_array_length", {LogicalType::VARIANT(), LogicalType::VARCHAR}, + LogicalType::UBIGINT, VariantArrayLengthFunction, VariantBindUtils::VariantPathBind, + nullptr); + fun_set.AddFunction(variant_exists); + + variant_exists.GetSignature().GetParameter(1).SetType(LogicalType::LIST(LogicalType::VARCHAR)); + variant_exists.SetReturnType(LogicalType::LIST(LogicalType::UBIGINT)); + fun_set.AddFunction(variant_exists); + + return fun_set; +} + +} // namespace duckdb diff --git a/src/duckdb/src/function/scalar/variant/variant_exists.cpp b/src/duckdb/src/function/scalar/variant/variant_exists.cpp index f95983138..6e8842a98 100644 --- a/src/duckdb/src/function/scalar/variant/variant_exists.cpp +++ b/src/duckdb/src/function/scalar/variant/variant_exists.cpp @@ -1,7 +1,7 @@ #include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/common/types/variant.hpp" +#include "duckdb/function/scalar/variant_path_function.hpp" #include "duckdb/function/scalar/variant_functions.hpp" -#include "duckdb/function/scalar/variant_utils.hpp" namespace duckdb { @@ -19,69 +19,17 @@ static ValidityMask CollectVariantExistence(const UnifiedVariantVectorData &vari return path_validity; } -static void UnaryVariantExists(const Vector &variant_vec, const vector &components, - Vector &result, const idx_t count) { - RecursiveUnifiedVectorFormat source_format; - Vector::RecursiveToUnifiedFormat(variant_vec, source_format); - const UnifiedVariantVectorData variant(source_format); - - const auto &path_validity = CollectVariantExistence(variant, components, count); - - result.Initialize(VectorDataInitialization::UNINITIALIZED, count); - auto row_writer = FlatVector::Writer(result, count); - - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - if (!variant.RowIsValid(row_idx)) { - row_writer.WriteNull(); - continue; - } - - if (path_validity.RowIsValid(row_idx)) { - row_writer.WriteValue(true); - } else { - row_writer.WriteValue(false); - } - } -} - -static void ManyVariantExists(const Vector &variant_vec, const vector> &paths, - Vector &result, const idx_t count) { - vector existence_by_path; - existence_by_path.reserve(paths.size()); - - RecursiveUnifiedVectorFormat source_format; - Vector::RecursiveToUnifiedFormat(variant_vec, source_format); - const UnifiedVariantVectorData variant(source_format); - - for (const auto &path : paths) { - existence_by_path.push_back(CollectVariantExistence(variant, path, count)); - } - - result.Initialize(VectorDataInitialization::UNINITIALIZED, count); - auto result_writer = FlatVector::Writer>(result, count); - - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - if (!variant.RowIsValid(row_idx)) { - result_writer.WriteNull(); - continue; - } - - auto row_writer = result_writer.WriteList(paths.size()); - idx_t path_idx = 0; - for (auto &path_existence_writer : row_writer) { - if (existence_by_path[path_idx].RowIsValid(row_idx)) { - path_existence_writer.WriteValue(true); - } else { - path_existence_writer.WriteValue(false); - } - - path_idx++; - } +static void WriteExistsResult(const UnifiedVariantVectorData &, VectorWriter &existence_writer, + const ValidityMask &path_validity, const idx_t row_idx) { + if (path_validity.RowIsValid(row_idx)) { + existence_writer.WriteValue(true); + } else { + existence_writer.WriteValue(false); } } static void VariantExistsFunction(DataChunk &input, ExpressionState &state, Vector &result) { - VariantUtils::ExecutePathFunction(input, state, result, UnaryVariantExists, ManyVariantExists); + VariantPathFunction::Execute(input, state, result, CollectVariantExistence, WriteExistsResult); } ScalarFunctionSet VariantExistsFun::GetFunctions() { diff --git a/src/duckdb/src/function/scalar/variant/variant_keys.cpp b/src/duckdb/src/function/scalar/variant/variant_keys.cpp index 81f44a728..5db13c144 100644 --- a/src/duckdb/src/function/scalar/variant/variant_keys.cpp +++ b/src/duckdb/src/function/scalar/variant/variant_keys.cpp @@ -1,8 +1,8 @@ #include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/common/vector/list_vector.hpp" #include "duckdb/common/types/variant.hpp" +#include "duckdb/function/scalar/variant_path_function.hpp" #include "duckdb/function/scalar/variant_functions.hpp" -#include "duckdb/function/scalar/variant_utils.hpp" namespace duckdb { @@ -65,86 +65,32 @@ static Vector CollectVariantKeys(const UnifiedVariantVectorData &variant, return key_ids; } -static void UnaryVariantKeys(const Vector &variant_vec, const vector &components, Vector &result, - const idx_t count) { - RecursiveUnifiedVectorFormat source_format; - Vector::RecursiveToUnifiedFormat(variant_vec, source_format); - const UnifiedVariantVectorData variant(source_format); - - auto key_ids = CollectVariantKeys(variant, components, count); +static void WriteKeysResult(const UnifiedVariantVectorData &variant, + VectorWriter> &result_writer, const Vector &key_ids, + const idx_t row_idx) { const auto &list_validity = FlatVector::Validity(key_ids); + if (!list_validity.RowIsValid(row_idx)) { + result_writer.WriteNull(); + return; + } + const auto list_entries = FlatVector::GetData(key_ids); const auto &child = ListVector::GetChild(key_ids); const auto key_ids_data = FlatVector::GetData(child); - result.Initialize(VectorDataInitialization::UNINITIALIZED, count); - auto result_writer = FlatVector::Writer>(result, count); - - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - if (!list_validity.RowIsValid(row_idx)) { - result_writer.WriteNull(); - continue; - } - - auto &entry = list_entries[row_idx]; - auto row_writer = result_writer.WriteList(entry.length); - - idx_t key_idx = 0; - for (auto &key_writer : row_writer) { - const auto key_id = key_ids_data[entry.offset + key_idx++]; - key_writer.WriteValue(variant.GetKey(row_idx, key_id)); - } - } -} - -static void ManyVariantKeys(const Vector &variant_vec, const vector> &paths, - Vector &result, const idx_t count) { - vector keys_by_path; - keys_by_path.reserve(paths.size()); - - RecursiveUnifiedVectorFormat source_format; - Vector::RecursiveToUnifiedFormat(variant_vec, source_format); - const UnifiedVariantVectorData variant(source_format); + auto &entry = list_entries[row_idx]; + auto row_writer = result_writer.WriteList(entry.length); - for (const auto &path : paths) { - keys_by_path.push_back(CollectVariantKeys(variant, path, count)); - } - - result.Initialize(VectorDataInitialization::UNINITIALIZED, count); - auto result_writer = FlatVector::Writer>>(result, count); - - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - auto row_writer = result_writer.WriteList(paths.size()); - idx_t path_idx = 0; - for (auto &path_keys_writer : row_writer) { - const auto &key_ids = keys_by_path[path_idx]; - const auto &list_validity = FlatVector::Validity(key_ids); - const auto list_entries = FlatVector::GetData(key_ids); - const auto &child = ListVector::GetChild(key_ids); - const auto key_ids_data = FlatVector::GetData(child); - - if (!list_validity.RowIsValid(row_idx)) { - path_keys_writer.WriteNull(); - path_idx++; - continue; - } - - auto &entry = list_entries[row_idx]; - auto keys_writer = path_keys_writer.WriteList(entry.length); - - idx_t key_idx = 0; - for (auto &key_writer : keys_writer) { - const auto key_id = key_ids_data[entry.offset + key_idx++]; - key_writer.WriteValue(variant.GetKey(row_idx, key_id)); - } - - path_idx++; - } + idx_t key_idx = 0; + for (auto &key_writer : row_writer) { + const auto key_id = key_ids_data[entry.offset + key_idx++]; + key_writer.WriteValue(variant.GetKey(row_idx, key_id)); } } static void VariantKeysFunction(DataChunk &input, ExpressionState &state, Vector &result) { - VariantUtils::ExecutePathFunction(input, state, result, UnaryVariantKeys, ManyVariantKeys); + VariantPathFunction::Execute>(input, state, result, CollectVariantKeys, + WriteKeysResult); } static void AddFunctionsWithParameterType(ScalarFunctionSet &fun_set, const LogicalType &input_type) { diff --git a/src/duckdb/src/function/scalar/variant/variant_utils.cpp b/src/duckdb/src/function/scalar/variant/variant_utils.cpp index 9d199c688..b246ab2c4 100644 --- a/src/duckdb/src/function/scalar/variant/variant_utils.cpp +++ b/src/duckdb/src/function/scalar/variant/variant_utils.cpp @@ -26,40 +26,6 @@ PhysicalType VariantDecimalData::GetPhysicalType() const { } } -void VariantUtils::ExecutePathFunction(DataChunk &input, const ExpressionState &state, Vector &result, - const unary_path_function_t &unary_fn, const many_path_function_t &many_fn) { - D_ASSERT(input.ColumnCount() == 1 || input.ColumnCount() == 2); - const auto count = input.size(); - const auto &variant_vec = input.data[0]; - - if (input.ColumnCount() == 2) { - const auto &path = input.data[1]; - D_ASSERT(path.GetVectorType() == VectorType::CONSTANT_VECTOR); - (void)path; - } - - auto &func_expr = state.expr.Cast(); - auto &info = func_expr.BindInfo()->Cast(); - auto n_columns = input.ColumnCount(); - - if (n_columns == 1) { - unary_fn(variant_vec, {}, result, count); - return; - } - - D_ASSERT(n_columns == 2); - const auto &path_type_id = input.data[1].GetType().id(); - - if (path_type_id == LogicalTypeId::VARCHAR) { - unary_fn(variant_vec, info.paths[0], result, count); - return; - } - if (path_type_id == LogicalTypeId::LIST) { - many_fn(variant_vec, info.paths, result, count); - return; - } -} - bool VariantUtils::IsNestedType(const UnifiedVariantVectorData &variant, idx_t row, uint32_t value_index) { auto type_id = variant.GetTypeId(row, value_index); return type_id == VariantLogicalType::ARRAY || type_id == VariantLogicalType::OBJECT; diff --git a/src/duckdb/src/function/table/system/duckdb_metrics.cpp b/src/duckdb/src/function/table/system/duckdb_metrics.cpp index b94648ec7..2dd25be1f 100644 --- a/src/duckdb/src/function/table/system/duckdb_metrics.cpp +++ b/src/duckdb/src/function/table/system/duckdb_metrics.cpp @@ -1,6 +1,6 @@ #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/metrics_manager.hpp" +#include "duckdb/main/profiler/metrics_manager.hpp" namespace duckdb { diff --git a/src/duckdb/src/function/table/system/enable_profiling.cpp b/src/duckdb/src/function/table/system/enable_profiling.cpp index 78506dc36..737a58e7b 100644 --- a/src/duckdb/src/function/table/system/enable_profiling.cpp +++ b/src/duckdb/src/function/table/system/enable_profiling.cpp @@ -21,7 +21,6 @@ static void EnableProfiling(ClientContext &context, TableFunctionInput &data, Da auto &client_config = ClientConfig::GetConfig(context); client_config.enable_profiler = true; - client_config.emit_profiler_output = true; if (!bind_data.format.IsNull() && !bind_data.save_location.IsNull()) { auto &file_system = FileSystem::GetFileSystem(context); @@ -32,7 +31,7 @@ static void EnableProfiling(ClientContext &context, TableFunctionInput &data, Da } EnableProfilingSetting::ResetLocal(context); - ProfileOutputSetting::ResetLocal(context); + ProfilingOutputSetting::ResetLocal(context); } if (!bind_data.format.IsNull()) { @@ -44,7 +43,7 @@ static void EnableProfiling(ClientContext &context, TableFunctionInput &data, Da } if (!bind_data.save_location.IsNull()) { - ProfileOutputSetting::SetLocal(context, bind_data.save_location); + ProfilingOutputSetting::SetLocal(context, bind_data.save_location); } if (!bind_data.mode.IsNull()) { @@ -119,7 +118,6 @@ static unique_ptr BindEnableProfiling(ClientContext &context, Tabl static void DisableProfiling(ClientContext &context, TableFunctionInput &data, DataChunk &output) { auto &client_config = ClientConfig::GetConfig(context); client_config.enable_profiler = false; - client_config.emit_profiler_output = false; } static unique_ptr BindDisableProfiling(ClientContext &context, TableFunctionBindInput &input, diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 058e63373..808d2e861 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 "0-dev8509" +#define DUCKDB_PATCH_VERSION "0-dev8617" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 6 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 1 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v1.6.0-dev8509" +#define DUCKDB_VERSION "v1.6.0-dev8617" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "b87f30f0c1" +#define DUCKDB_SOURCE_ID "ccbdf9f7c7" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/common/enum_util.hpp b/src/duckdb/src/include/duckdb/common/enum_util.hpp index 33021ac26..9326eea29 100644 --- a/src/duckdb/src/include/duckdb/common/enum_util.hpp +++ b/src/duckdb/src/include/duckdb/common/enum_util.hpp @@ -194,8 +194,6 @@ enum class ExceptionFormatValueType : uint8_t; enum class ExceptionType : uint8_t; -enum class ExplainFormat : uint8_t; - enum class ExplainOutputType : uint8_t; enum class ExplainType : uint8_t; @@ -252,6 +250,8 @@ enum class GeometryStorageType : uint8_t; enum class GeometryType : uint8_t; +enum class GroupByExpressionInfoType : uint8_t; + enum class HLLStorageType : uint8_t; enum class HTTPStatusCode : uint16_t; @@ -380,8 +380,6 @@ enum class PreparedStatementMode : uint8_t; enum class PreserveOrderType : uint8_t; -enum class ProfilerPrintFormat : uint8_t; - enum class ProfilingCoverage : uint8_t; enum class ProfilingParameterNames : uint8_t; @@ -802,9 +800,6 @@ const char* EnumUtil::ToChars(ExceptionFormatValueType template<> const char* EnumUtil::ToChars(ExceptionType value); -template<> -const char* EnumUtil::ToChars(ExplainFormat value); - template<> const char* EnumUtil::ToChars(ExplainOutputType value); @@ -889,6 +884,9 @@ const char* EnumUtil::ToChars(GeometryStorageType value); template<> const char* EnumUtil::ToChars(GeometryType value); +template<> +const char* EnumUtil::ToChars(GroupByExpressionInfoType value); + template<> const char* EnumUtil::ToChars(HLLStorageType value); @@ -1081,9 +1079,6 @@ const char* EnumUtil::ToChars(PreparedStatementMode value template<> const char* EnumUtil::ToChars(PreserveOrderType value); -template<> -const char* EnumUtil::ToChars(ProfilerPrintFormat value); - template<> const char* EnumUtil::ToChars(ProfilingCoverage value); @@ -1592,9 +1587,6 @@ ExceptionFormatValueType EnumUtil::FromString(const ch template<> ExceptionType EnumUtil::FromString(const char *value); -template<> -ExplainFormat EnumUtil::FromString(const char *value); - template<> ExplainOutputType EnumUtil::FromString(const char *value); @@ -1679,6 +1671,9 @@ GeometryStorageType EnumUtil::FromString(const char *value) template<> GeometryType EnumUtil::FromString(const char *value); +template<> +GroupByExpressionInfoType EnumUtil::FromString(const char *value); + template<> HLLStorageType EnumUtil::FromString(const char *value); @@ -1871,9 +1866,6 @@ PreparedStatementMode EnumUtil::FromString(const char *va template<> PreserveOrderType EnumUtil::FromString(const char *value); -template<> -ProfilerPrintFormat EnumUtil::FromString(const char *value); - template<> ProfilingCoverage EnumUtil::FromString(const char *value); diff --git a/src/duckdb/src/include/duckdb/common/enums/explain_format.hpp b/src/duckdb/src/include/duckdb/common/enums/explain_format.hpp deleted file mode 100644 index 149e8c33f..000000000 --- a/src/duckdb/src/include/duckdb/common/enums/explain_format.hpp +++ /dev/null @@ -1,17 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/explain_format.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/typedefs.hpp" - -namespace duckdb { - -enum class ExplainFormat : uint8_t { DEFAULT, TEXT, JSON, HTML, GRAPHVIZ, YAML, MERMAID }; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/profiler_format.hpp b/src/duckdb/src/include/duckdb/common/enums/profiler_format.hpp deleted file mode 100644 index 9cd1206b9..000000000 --- a/src/duckdb/src/include/duckdb/common/enums/profiler_format.hpp +++ /dev/null @@ -1,17 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/profiler_format.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/constants.hpp" - -namespace duckdb { - -enum class ProfilerPrintFormat : uint8_t { QUERY_TREE, JSON, QUERY_TREE_OPTIMIZER, NO_OUTPUT, HTML, GRAPHVIZ, MERMAID }; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/extra_type_info.hpp b/src/duckdb/src/include/duckdb/common/extra_type_info.hpp index 81a20bc22..3a6c4d206 100644 --- a/src/duckdb/src/include/duckdb/common/extra_type_info.hpp +++ b/src/duckdb/src/include/duckdb/common/extra_type_info.hpp @@ -56,6 +56,9 @@ struct ExtraTypeInfo { static shared_ptr Deserialize(Deserializer &source); virtual shared_ptr Copy() const; virtual shared_ptr DeepCopy() const; + //! Copy the base fields (alias, extension info) into "target" - used by Copy/DeepCopy implementations that + //! reconstruct the type info instead of copy-constructing it + void CopyBaseInfo(ExtraTypeInfo &target) const; template TARGET &Cast() { @@ -174,6 +177,7 @@ struct EnumTypeInfo : public ExtraTypeInfo { static PhysicalType DictType(idx_t size); static LogicalType CreateType(const Vector &ordered_data, idx_t size); + static shared_ptr CreateTypeInfo(const Vector &ordered_data, idx_t size); void Serialize(Serializer &serializer) const override; static shared_ptr Deserialize(Deserializer &source); diff --git a/src/duckdb/src/include/duckdb/common/render_tree.hpp b/src/duckdb/src/include/duckdb/common/render_tree.hpp index 0ef5a1b36..582c543b5 100644 --- a/src/duckdb/src/include/duckdb/common/render_tree.hpp +++ b/src/duckdb/src/include/duckdb/common/render_tree.hpp @@ -12,7 +12,7 @@ #include "duckdb/common/string.hpp" #include "duckdb/common/optional_ptr.hpp" #include "duckdb/main/query_profiler.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" namespace duckdb { class LogicalOperator; diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer.hpp index 981836b63..a33ba3e23 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer.hpp @@ -9,12 +9,19 @@ #pragma once #include "duckdb/common/constants.hpp" +#include "duckdb/common/unordered_map.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/render_tree.hpp" namespace duckdb { +class QueryProfiler; + +//! TreeRenderer renders a plan/operator tree (for EXPLAIN) or a query profiler's output in a particular format. +//! It is the single renderer abstraction: each format (text, JSON, HTML, GraphViz, Mermaid, YAML) is one subclass +//! that handles both EXPLAIN rendering and profiler output. New formats are added in CreateRenderer. class TreeRenderer { public: explicit TreeRenderer() { @@ -25,13 +32,30 @@ class TreeRenderer { public: void ToStream(RenderTree &root, std::ostream &ss); virtual void ToStreamInternal(RenderTree &root, std::ostream &ss) = 0; - static unique_ptr CreateRenderer(ExplainFormat format); + //! Create a TreeRenderer for the given format name (e.g. "json", "text"). The name is matched case-insensitively + //! and throws if it is not recognized. Returns nullptr for formats that render no output (i.e. "no_output"). + //! This is the primary, name-based factory; new render formats are added here. + static unique_ptr CreateRenderer(const string &name); + //! Create a TreeRenderer for the given ProfilerPrintFormat (thin wrapper over the name-based factory). + static unique_ptr CreateRenderer(const ProfilerPrintFormat &format); + + //! Generic configuration of the renderer: passes renderer settings (e.g. from the "profiling_renderer_settings" + //! setting) to the renderer. Renderers override this to handle the settings they support, and throw on invalid + //! setting values. Unrecognized settings are ignored - they may be intended for a different renderer. + virtual void Configure(const unordered_map &settings) { + } virtual bool UsesRawKeyNames() { return false; } virtual void Render(const ProfilingNode &op, std::ostream &ss) { } + + //! Render the profiler's output in this format. Only called when profiling is enabled. The base implementation + //! renders the profiling node tree; formats with richer output (text, JSON) override this. + virtual string RenderProfiler(const QueryProfiler &profiler); + //! The message shown (in this format) when profiling is disabled. + virtual string RenderProfilerDisabled(); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/graphviz_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/graphviz_tree_renderer.hpp index a4ed7f75f..9476107d5 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/graphviz_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/graphviz_tree_renderer.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" @@ -39,6 +39,8 @@ class GRAPHVIZTreeRenderer : public TreeRenderer { void Render(const Pipeline &op, std::ostream &ss); void ToStreamInternal(RenderTree &root, std::ostream &ss) override; + + string RenderProfilerDisabled() override; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/html_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/html_tree_renderer.hpp index e5d038a27..d19319149 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/html_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/html_tree_renderer.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" @@ -39,6 +39,8 @@ class HTMLTreeRenderer : public TreeRenderer { void Render(const Pipeline &op, std::ostream &ss); void ToStreamInternal(RenderTree &root, std::ostream &ss) override; + + string RenderProfilerDisabled() override; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/json_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/json_tree_renderer.hpp index 15e7c5037..097b375b7 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/json_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/json_tree_renderer.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" @@ -39,6 +39,10 @@ class JSONTreeRenderer : public TreeRenderer { void Render(const Pipeline &op, std::ostream &ss); void ToStreamInternal(RenderTree &root, std::ostream &ss) override; + + //! Profiler JSON output: the full query profile result tree (with query-level metrics) + string RenderProfiler(const QueryProfiler &profiler) override; + string RenderProfilerDisabled() override; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/mermaid_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/mermaid_tree_renderer.hpp index 63d87e77e..d7ff98cb5 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/mermaid_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/mermaid_tree_renderer.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" @@ -39,6 +39,8 @@ class MermaidTreeRenderer : public TreeRenderer { void Render(const Pipeline &op, std::ostream &ss); void ToStreamInternal(RenderTree &root, std::ostream &ss) override; + + string RenderProfilerDisabled() override; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/text_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/text_tree_renderer.hpp index fe1b1e2b7..6cac2705a 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/text_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/text_tree_renderer.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" @@ -21,21 +21,10 @@ class Pipeline; struct PipelineRenderNode; struct TextTreeRendererConfig { - void EnableDetailed() { - max_extra_lines = 1000; - detailed = true; - } - - void EnableStandard() { - max_extra_lines = 30; - detailed = false; - } - idx_t maximum_render_width = 240; idx_t node_render_width = 29; idx_t minimum_render_width = 15; idx_t max_extra_lines = 30; - bool detailed = false; // Formatting options char thousand_separator = ','; @@ -93,12 +82,11 @@ class TextTreeRenderer : public TreeRenderer { void ToStreamInternal(RenderTree &root, std::ostream &ss) override; - void EnableDetailed() { - config.EnableDetailed(); - } - void EnableStandard() { - config.EnableStandard(); - } + //! Profiler text output: the framed query tree (with phase timings, total time, etc.) + string RenderProfiler(const QueryProfiler &profiler) override; + + void Configure(const unordered_map &settings) override; + bool UsesRawKeyNames() override { return true; } diff --git a/src/duckdb/src/include/duckdb/common/tree_renderer/yaml_tree_renderer.hpp b/src/duckdb/src/include/duckdb/common/tree_renderer/yaml_tree_renderer.hpp index 3a5278e16..85d8b7af9 100644 --- a/src/duckdb/src/include/duckdb/common/tree_renderer/yaml_tree_renderer.hpp +++ b/src/duckdb/src/include/duckdb/common/tree_renderer/yaml_tree_renderer.hpp @@ -1,6 +1,6 @@ #pragma once -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/render_tree.hpp" diff --git a/src/duckdb/src/include/duckdb/common/types/list_segment.hpp b/src/duckdb/src/include/duckdb/common/types/list_segment.hpp index 85b5d075b..f43947e4b 100644 --- a/src/duckdb/src/include/duckdb/common/types/list_segment.hpp +++ b/src/duckdb/src/include/duckdb/common/types/list_segment.hpp @@ -32,6 +32,16 @@ struct LinkedList { ListSegment *last_segment; }; +struct ListSegmentScanState { + //! The current segment + const ListSegment *segment = nullptr; + //! The offset of the next row to be scanned within the current segment + idx_t offset = 0; + //! The scan states for the children of the current segment (if any) + //! These are (re-)initialized by the scan whenever it moves to a new segment + vector children; +}; + // forward declarations struct ListSegmentFunctions; typedef ListSegment *(*create_segment_t)(const ListSegmentFunctions &functions, ArenaAllocator &allocator, @@ -39,21 +49,36 @@ typedef ListSegment *(*create_segment_t)(const ListSegmentFunctions &functions, typedef void (*write_data_to_segment_t)(const ListSegmentFunctions &functions, ArenaAllocator &allocator, ListSegment *segment, RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx); -typedef void (*read_data_from_segment_t)(const ListSegmentFunctions &functions, const ListSegment *segment, - Vector &result, idx_t &total_count); +//! Scans up to "count" rows from the state's current position into the result vector at result_offset, +//! advancing the state - returns the number of rows scanned (less than "count" only if the scan is exhausted) +typedef idx_t (*scan_data_t)(const ListSegmentFunctions &functions, ListSegmentScanState &state, idx_t count, + Vector &result, idx_t result_offset); struct ListSegmentFunctions { create_segment_t create_segment; write_data_to_segment_t write_data; - read_data_from_segment_t read_data; + scan_data_t scan_data; uint16_t initial_capacity = ListSegment::INITIAL_CAPACITY; vector child_functions; void AppendRow(ArenaAllocator &allocator, LinkedList &linked_list, RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx) const; + //! Append all rows of the given list entry (indexing into child_data) to the linked list + void AppendListEntry(ArenaAllocator &allocator, LinkedList &linked_list, RecursiveUnifiedVectorFormat &child_data, + const list_entry_t &list_entry) const; void BuildListVector(const LinkedList &linked_list, Vector &result, idx_t total_count) const; + + void InitializeScan(const LinkedList &linked_list, ListSegmentScanState &state) const; + //! Scans up to STANDARD_VECTOR_SIZE rows into the (freshly initialized) result vector, + //! returning the number of rows scanned - 0 when the scan is exhausted + idx_t Scan(ListSegmentScanState &state, Vector &result) const; + + //! Build a LIST result vector from a set of linked lists - one per row, written at rows [offset, offset + count). + //! Rows with an empty linked list (total_capacity == 0) are set to NULL. + void BuildLists(const vector &linked_lists, Vector &result, idx_t offset) const; }; void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType &type); + } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_explain_analyze.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_explain_analyze.hpp index b0d83db96..37ad47086 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_explain_analyze.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_explain_analyze.hpp @@ -10,7 +10,7 @@ #include "duckdb/execution/physical_operator.hpp" #include "duckdb/planner/expression.hpp" -#include "duckdb/common/enums/explain_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" namespace duckdb { @@ -19,12 +19,13 @@ class PhysicalExplainAnalyze : public PhysicalOperator { static constexpr const PhysicalOperatorType TYPE = PhysicalOperatorType::EXPLAIN_ANALYZE; public: - PhysicalExplainAnalyze(PhysicalPlan &physical_plan, vector types, ExplainFormat format) - : PhysicalOperator(physical_plan, PhysicalOperatorType::EXPLAIN_ANALYZE, std::move(types), 1), format(format) { + PhysicalExplainAnalyze(PhysicalPlan &physical_plan, vector types, ProfilerPrintFormat format) + : PhysicalOperator(physical_plan, PhysicalOperatorType::EXPLAIN_ANALYZE, std::move(types), 1), + format(std::move(format)) { } public: - ExplainFormat format; + ProfilerPrintFormat format; public: // Source interface diff --git a/src/duckdb/src/include/duckdb/execution/physical_operator.hpp b/src/duckdb/src/include/duckdb/execution/physical_operator.hpp index ba1082140..e7872e34a 100644 --- a/src/duckdb/src/include/duckdb/execution/physical_operator.hpp +++ b/src/duckdb/src/include/duckdb/execution/physical_operator.hpp @@ -12,7 +12,7 @@ #include "duckdb/common/arena_linked_list.hpp" #include "duckdb/common/case_insensitive_map.hpp" #include "duckdb/common/common.hpp" -#include "duckdb/common/enums/explain_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" #include "duckdb/common/enums/operator_result_type.hpp" #include "duckdb/common/enums/order_preservation_type.hpp" #include "duckdb/common/enums/physical_operator_type.hpp" @@ -74,7 +74,7 @@ class PhysicalOperator { return InsertionOrderPreservingMap(); } static void SetEstimatedCardinality(InsertionOrderPreservingMap &result, idx_t estimated_cardinality); - virtual string ToString(ExplainFormat format = ExplainFormat::DEFAULT) const; + virtual string ToString(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()) const; void Print() const; virtual vector> GetChildren() const; diff --git a/src/duckdb/src/include/duckdb/function/aggregate/distributive_function_utils.hpp b/src/duckdb/src/include/duckdb/function/aggregate/distributive_function_utils.hpp index 820bcfd1d..de0391839 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate/distributive_function_utils.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate/distributive_function_utils.hpp @@ -41,7 +41,7 @@ template struct EmptyValAggregate : public ClusteredStateCopy { template static void UpdateClusteredLocal(STATE &local, const INPUT_TYPE &input) { - local.empty = false; + local.is_set = true; using value_type = decltype(local.val); local.val = REDUCE_OP::template Operation(local.val, value_type(input)); } @@ -56,19 +56,19 @@ struct EmptyValAggregate : public ClusteredStateCopy { template static void Initialize(STATE &state) { state.val = INIT_OP::template Value(); - state.empty = true; + state.is_set = false; } template static void Combine(const STATE &source, STATE &target, AggregateInputData &) { using value_type = decltype(target.val); target.val = REDUCE_OP::template Operation(target.val, source.val); - target.empty = target.empty && source.empty; + target.is_set = target.is_set || source.is_set; } template static void Finalize(STATE &state, T &target, AggregateFinalizeData &finalize_data) { - if (state.empty) { + if (!state.is_set) { finalize_data.ReturnNull(); return; } diff --git a/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp b/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp index eb89794fb..29cad0eac 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp @@ -91,6 +91,16 @@ struct MaxFun { static AggregateFunctionSet GetFunctions(); }; +struct DecimalAverageFun { + static constexpr const char *Name = "decimal_average"; + static constexpr const char *Parameters = "arg"; + static constexpr const char *Description = "Computes the average of a DECIMAL column using exact integer arithmetic with banker's rounding. Returns a DECIMAL with the same width and scale as the input."; + static constexpr const char *Example = "decimal_average(col::DECIMAL(18,2))"; + static constexpr const char *Categories = ""; + + static AggregateFunctionSet GetFunctions(); +}; + struct CombineAggrFun { static constexpr const char *Name = "combine_aggr"; static constexpr const char *Parameters = "arg"; diff --git a/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp b/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp new file mode 100644 index 000000000..8dd438fb4 --- /dev/null +++ b/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/aggregate/list_aggregate.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/types/list_segment.hpp" +#include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/function/aggregate_function.hpp" + +namespace duckdb { + +//! The state of the "list" aggregate - shared by aggregates that buffer their input in a linked list +struct ListAggState { + LinkedList linked_list; + + using STATE_TYPE = StateListType; +}; + +struct ListFunction { + static bool IgnoreNull() { + return false; + } + + static LogicalType GetElementType(AggregateInputData &aggr_input_data) { + return ListType::GetChildType(aggr_input_data.function.GetReturnType()); + } +}; + +//! Appends the i-th input row to the i-th state's linked list. +//! When IGNORE_NULLS is set, NULL input rows are not appended. +template +inline void ListUpdateFunction(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &state_vector, idx_t count) { + D_ASSERT(input_count == 1); + auto &input = inputs[0]; + RecursiveUnifiedVectorFormat input_data; + Vector::RecursiveToUnifiedFormat(input, input_data); + + auto states = state_vector.Values(); + + ListSegmentFunctions functions; + GetSegmentDataFunctions(functions, input.GetType()); + + for (idx_t i = 0; i < count; i++) { + if (IGNORE_NULLS) { + const auto idx = input_data.unified.sel->get_index(i); + if (!input_data.unified.validity.RowIsValid(idx)) { + continue; + } + } + auto &state = *states[i].GetValue(); + aggr_input_data.allocator.AlignNext(); + functions.AppendRow(aggr_input_data.allocator, state.linked_list, input_data, i); + } +} + +inline void ListAbsorbFunction(Vector &states_vector, Vector &combined, AggregateInputData &aggr_input_data, + idx_t count) { + D_ASSERT(aggr_input_data.combine_type == AggregateCombineType::ALLOW_DESTRUCTIVE); + + auto states = states_vector.Values(); + auto combined_ptr = FlatVector::GetDataMutable(combined); + for (idx_t i = 0; i < count; i++) { + auto &state = *states[i].GetValue(); + if (state.linked_list.total_capacity == 0) { + // NULL, no need to append + // this can happen when adding a FILTER to the grouping, e.g., + // LIST(i) FILTER (WHERE i <> 3) + continue; + } + + if (combined_ptr[i]->linked_list.total_capacity == 0) { + combined_ptr[i]->linked_list = state.linked_list; + continue; + } + + // append the linked list + combined_ptr[i]->linked_list.last_segment->next = state.linked_list.first_segment; + combined_ptr[i]->linked_list.last_segment = state.linked_list.last_segment; + combined_ptr[i]->linked_list.total_capacity += state.linked_list.total_capacity; + } +} + +//! OP provides GetElementType(aggr_input_data), returning the type of the values stored in the linked list +template +void ListCombineFunction(Vector &states_vector, Vector &combined, AggregateInputData &aggr_input_data, idx_t count) { + // Can we use destructive combining? + if (aggr_input_data.combine_type == AggregateCombineType::ALLOW_DESTRUCTIVE) { + ListAbsorbFunction(states_vector, combined, aggr_input_data, count); + return; + } + + auto states = states_vector.Values(); + auto combined_ptr = FlatVector::GetDataMutable(combined); + + auto element_type = OP::GetElementType(aggr_input_data); + ListSegmentFunctions functions; + GetSegmentDataFunctions(functions, element_type); + + for (idx_t i = 0; i < count; i++) { + auto &source = *states[i].GetValue(); + auto &target = *combined_ptr[i]; + + const auto entry_count = source.linked_list.total_capacity; + Vector input(element_type, entry_count); + functions.BuildListVector(source.linked_list, input, 0); + + RecursiveUnifiedVectorFormat input_data; + Vector::RecursiveToUnifiedFormat(input, input_data); + + functions.AppendListEntry(aggr_input_data.allocator, target.linked_list, input_data, + list_entry_t(0, entry_count)); + } +} + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/aggregate/sort_key_helpers.hpp b/src/duckdb/src/include/duckdb/function/aggregate/sort_key_helpers.hpp index 86ce51c69..e7f13fcbc 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate/sort_key_helpers.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate/sort_key_helpers.hpp @@ -24,9 +24,9 @@ struct AggregateSortKeyHelpers { auto modifiers = OrderModifiers(ORDER_TYPE, OrderByNullType::NULLS_LAST); CreateSortKeyHelpers::CreateSortKey(input, modifiers, sort_key); - UnifiedVectorFormat idata; + optional input_validity; if (IGNORE_NULLS) { - input.ToUnifiedFormat(idata); + input_validity = input.Validity(); } UnifiedVectorFormat kdata; @@ -40,8 +40,7 @@ struct AggregateSortKeyHelpers { for (idx_t i = 0; i < count; i++) { const auto sidx = sdata.sel->get_index(i); if (IGNORE_NULLS) { - auto idx = idata.sel->get_index(i); - if (!idata.validity.RowIsValid(idx)) { + if (!input_validity.value().IsValid(i)) { continue; } } diff --git a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp index fc7b2e1db..41275fc96 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp @@ -564,35 +564,15 @@ class AggregateFunction : public BaseAggregateFunction, public SimpleFunction { } public: + //! Returns the logical type for state type ST, resolving types that are only known after binding + //! (sort keys, linked lists and StateString fields) from the bound aggregate function. + //! Defined out-of-line (after BoundAggregateFunction is complete). + template + static LogicalType BuildStateLogical(const BoundAggregateFunction &bound_function); + + //! Defined out-of-line (after BoundAggregateFunction is complete) so the lambda body can call GetReturnType(). template - static void WireStructStateType(AggregateFunction &result) { - if constexpr (HasStructStateType::value) { - if constexpr (IsOptionalStateType::value) { - result.SetStructStateExport([](const BoundAggregateFunction &) { - using T = typename STATE::STATE_TYPE::value_type; - if constexpr (IsStructStateType::value) { - return AggregateStateLayout(T::GetLogicalType(STATE::STATE_NAMES), - AlignValue(sizeof(STATE)), true); - } else { - return AggregateStateLayout(PrimitiveToLogicalType(), AlignValue(sizeof(STATE)), - true); - } - }); - } else { - result.SetStructStateExport([](const BoundAggregateFunction &) { - AggregateStateLayout layout; - layout.type = STATE::STATE_TYPE::GetLogicalType(STATE::STATE_NAMES); - layout.total_state_size = AlignValue(sizeof(STATE)); - STATE::STATE_TYPE::PopulateField(layout.field); - return layout; - }); - } - } else if constexpr (HasPrimitiveLogicalType::value) { - result.SetStructStateExport([](const BoundAggregateFunction &) { - return AggregateStateLayout(PrimitiveToLogicalType(), AlignValue(sizeof(STATE))); - }); - } - } + static void WireStructStateType(AggregateFunction &result); template static idx_t StateSize(const BoundAggregateFunction &) { @@ -720,4 +700,49 @@ class BoundAggregateFunction : public BaseAggregateFunction, public BoundSimpleF } }; +// Defined here (after BoundAggregateFunction is complete) so the lambda body can call GetReturnType(). +template +inline void AggregateFunction::WireStructStateType(AggregateFunction &result) { + if constexpr (HasStructStateType::value) { + using ST = typename STATE::STATE_TYPE; + result.SetStructStateExport([](const BoundAggregateFunction &bound) { + AggregateStateLayout layout; + if (bound.GetReturnType().IsAggregateState()) { + // the function has been modified for state export (see ExportAggregateFunction::SetStateExport) - + // its return type IS the state type already + layout.type = bound.GetReturnType(); + } else { + layout.type = AggregateFunction::BuildStateLogical(bound); + } + layout.total_state_size = AlignValue(sizeof(STATE)); + layout.field = BuildStateField(); + AggregateStateField::PopulateListFunctions(layout.type, layout.field); + return layout; + }); + } else if constexpr (HasPrimitiveLogicalType::value) { + result.SetStructStateExport([](const BoundAggregateFunction &) { + return AggregateStateLayout(PrimitiveToLogicalType(), AlignValue(sizeof(STATE))); + }); + } +} + +// Defined here (after BoundAggregateFunction is complete) so the body can access the bound function's types. +template +inline LogicalType AggregateFunction::BuildStateLogical(const BoundAggregateFunction &bound_function) { + // the runtime types of the bound function - used to resolve StateReturnType/StateInputType sources + StateLayoutTypeInfo info {bound_function.GetReturnType(), bound_function.GetArguments()}; + if constexpr (IsStateListType::value) { + return ResolveStateSourceType(info); + } else if constexpr (IsOptionalStateType::value) { + using V = typename ST::value_type; + if constexpr (IsStructStateType::value) { + return V::GetLogicalType(STATE::STATE_NAMES, info); + } else { + return FieldToLogicalType(info); + } + } else { + return ST::GetLogicalType(STATE::STATE_NAMES, info); + } +} + } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/aggregate_state.hpp b/src/duckdb/src/include/duckdb/function/aggregate_state.hpp index ca8e9930f..0b0a9f6d8 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate_state.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate_state.hpp @@ -85,6 +85,7 @@ struct AggregateFinalizeData { AggregateInputData &input; idx_t result_idx; idx_t result_count; + unique_ptr local_state; inline void ReturnNull() { switch (result.GetVectorType()) { diff --git a/src/duckdb/src/include/duckdb/function/aggregate_state_layout.hpp b/src/duckdb/src/include/duckdb/function/aggregate_state_layout.hpp index f98ff3799..134357b67 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate_state_layout.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate_state_layout.hpp @@ -7,8 +7,10 @@ #pragma once +#include "duckdb/common/enums/order_type.hpp" #include "duckdb/common/helper.hpp" #include "duckdb/common/type_util.hpp" +#include "duckdb/common/types/list_segment.hpp" namespace duckdb { @@ -33,6 +35,91 @@ struct IsOptionalStateType : std::false_type {}; template struct IsOptionalStateType> : std::true_type {}; +//! Phantom marker type: resolves to the return type of the bound aggregate function. +struct StateReturnType {}; + +//! Phantom marker type: resolves to the type of the bound aggregate function's INDEX'th argument. +template +struct StateInputType { + static constexpr idx_t index = INDEX; +}; + +//! Detection trait: true when T is StateInputType for some INDEX. +template +struct IsStateInputType : std::false_type {}; +template +struct IsStateInputType> : std::true_type {}; + +//! The runtime types of a bound aggregate function - used to resolve the logical types of state fields that are +//! only known after binding (see StateReturnType / StateInputType). +struct StateLayoutTypeInfo { + const LogicalType &return_type; + const vector &argument_types; +}; + +//! Resolves a type source marker (StateReturnType or StateInputType) to a LogicalType. +template +LogicalType ResolveStateSourceType(const StateLayoutTypeInfo &info) { + if constexpr (IsStateInputType::value) { + D_ASSERT(SOURCE::index < info.argument_types.size()); + return info.argument_types[SOURCE::index]; + } else { + static_assert(std::is_same::value, + "the type source must be StateReturnType or StateInputType"); + return info.return_type; + } +} + +//! Phantom marker type for use inside OptionalStateType. +//! Signals that the field stores a binary sort key (string_t) that must be decoded/encoded +//! via CreateSortKeyHelpers when exporting/importing aggregate state. +//! SOURCE describes where the decoded logical type comes from; ORDER is the ordering used when creating the sort key. +template +struct StateSortKey { + using SOURCE_TYPE = SOURCE; + static constexpr OrderType order_type = ORDER; +}; + +//! Detection trait: true when T is StateSortKey for some SOURCE/ORDER. +template +struct IsStateSortKeyType : std::false_type {}; +template +struct IsStateSortKeyType> : std::true_type {}; + +//! Phantom marker type for fields that are physically stored as T, while their exported logical type comes from +//! the bound aggregate function as described by SOURCE - e.g. exporting a string_t as VARCHAR, BLOB or BIT, or +//! an int64_t "by" value as TIMESTAMP. +template +struct StateTypedValue { + using PHYSICAL_TYPE = T; + using SOURCE_TYPE = SOURCE; +}; + +//! Detection trait: true when T is StateTypedValue for some V/SOURCE. +template +struct IsStateTypedValueType : std::false_type {}; +template +struct IsStateTypedValueType> : std::true_type {}; + +//! Shorthand for values physically stored as a string_t. +template +using StateString = StateTypedValue; + +//! Phantom marker type for use as an aggregate STATE's STATE_TYPE. +//! Signals that the state is a LinkedList (see list_segment.hpp) holding the rows of a LIST value. +//! Export reads the linked list into a LIST vector; import appends the LIST value's rows back into a linked list. +//! SOURCE describes where the list's logical type comes from. +template +struct StateListType { + using SOURCE_TYPE = SOURCE; +}; + +//! Detection trait: true when T is StateListType for some SOURCE. +template +struct IsStateListType : std::false_type {}; +template +struct IsStateListType> : std::true_type {}; + //! Detection trait: true when STATE is itself a C++ primitive type mappable to a LogicalType via PrimitiveToLogicalType template struct HasPrimitiveLogicalType : std::false_type {}; @@ -87,28 +174,109 @@ template <> struct HasPrimitiveLogicalType : std::true_type {}; //! Maps a single C++ field type to a LogicalType. -//! OptionalStateType → PrimitiveToLogicalType() (the optional encoding is captured in -//! AggregateStateField::is_optional) T with STATE_TYPE → nested struct type otherwise → PrimitiveToLogicalType() +//! info holds the runtime types of the bound function - used to resolve fields whose logical type cannot be +//! expressed statically (sort keys and StateTypedValue fields). +//! OptionalStateType → the type of T (the optional encoding is captured in AggregateStateField::kind) +//! StateSortKey / StateTypedValue → the resolved SOURCE type +//! T with STATE_TYPE → nested struct type otherwise → PrimitiveToLogicalType() template -LogicalType FieldToLogicalType() { +LogicalType FieldToLogicalType(const StateLayoutTypeInfo &info) { if constexpr (IsOptionalStateType::value) { - return PrimitiveToLogicalType(); + return FieldToLogicalType(info); + } else if constexpr (IsStateSortKeyType::value || IsStateTypedValueType::value || IsStateListType::value) { + return ResolveStateSourceType(info); } else if constexpr (HasStructStateType::value) { - return T::STATE_TYPE::GetLogicalType(T::STATE_NAMES); + return T::STATE_TYPE::GetLogicalType(T::STATE_NAMES, info); } else { return PrimitiveToLogicalType(); } } +//! Describes the kind of a single field within an aggregate state layout. +enum class AggregateFieldKind { + //! Scalar value. field_offset = byte offset of the value. + PRIMITIVE, + //! Compound struct. field_offset = byte offset of the struct base. + //! children = one entry per struct member (offsets relative to this field's base). + STRUCT, + //! Nullable wrapper. field_offset = byte offset of the bool is_set flag. + //! children has exactly one entry: the value field (PRIMITIVE, STRUCT, SORT_KEY or LIST). + //! The value field's field_offset is relative to the same parent base as this field. + OPTIONAL_VALUE, + //! Binary sort key (stored as string_t). field_offset = byte offset of the string_t. + //! sort_key_order carries the ordering. Always appears as children[0] of an OPTIONAL_VALUE field. + SORT_KEY, + //! Linked list of values (stored as a LinkedList, see list_segment.hpp). field_offset = byte offset of the + //! LinkedList. Exported as a LIST value; an empty linked list is exported as NULL. + //! The segment functions used to read/write the linked list live in AggregateStateField::list_functions. + LIST, +}; + //! Per-field layout information within an aggregate state. -//! field_offset: byte offset of this field relative to the parent struct's base. -//! is_optional: true when this field is an OptionalStateType — physically T value + bool is_set at -//! field_offset+sizeof(T). children: non-empty only when the field is itself a STRUCT; each child's offset is relative -//! to this field's base. struct AggregateStateField { idx_t field_offset = 0; - bool is_optional = false; + //! Physical byte size of the data described by this field (including nested struct members). + //! For OPTIONAL_VALUE: includes is_set bool (field_offset + sizeof(bool)). + idx_t field_size = 0; + //! The C++ alignment (alignof) of the field's data - the offsets in the real state structs depend on it, + //! and it is platform-dependent (e.g. string_t is 8-byte aligned on 64-bit platforms but 4-byte aligned on + //! 32-bit Windows), so it must be recorded from the actual C++ types rather than derived from the field size + idx_t field_alignment = 0; + AggregateFieldKind kind = AggregateFieldKind::PRIMITIVE; + OrderType sort_key_order = OrderType::ASCENDING; // only meaningful when kind == SORT_KEY vector children; + //! The segment functions used to read/write the linked list - only set when kind is LIST + //! (populated by PopulateListFunctions, which requires the resolved logical type) + ListSegmentFunctions list_functions; + + //! The alignment of this field when placed as a struct member, mirroring the C++ struct layout rules. + //! For OPTIONAL_VALUE the alignment is that of the wrapped value - the trailing is_set bool does not affect it. + idx_t GetAlignment() const { + if (kind == AggregateFieldKind::OPTIONAL_VALUE) { + D_ASSERT(children.size() == 1); + return children[0].GetAlignment(); + } + if (field_alignment != 0) { + return field_alignment; + } + return MinValue(field_size, 8); + } + + //! Shift this field's offsets to place it at `offset` within its parent. + //! The value child of an OPTIONAL_VALUE is relative to the same parent base as the optional itself, so it shifts + //! along; STRUCT children are relative to the struct's own base and stay untouched. + void ShiftBase(idx_t offset) { + field_offset += offset; + if (kind == AggregateFieldKind::OPTIONAL_VALUE) { + D_ASSERT(children.size() == 1); + children[0].ShiftBase(offset); + } + } + + //! Populate the segment functions of all LIST fields in the field tree, walking the (resolved) logical type + //! alongside the fields. Called once when the layout is created. + static void PopulateListFunctions(const LogicalType &type, AggregateStateField &field) { + switch (field.kind) { + case AggregateFieldKind::LIST: + D_ASSERT(type.id() == LogicalTypeId::LIST); + GetSegmentDataFunctions(field.list_functions, ListType::GetChildType(type)); + break; + case AggregateFieldKind::OPTIONAL_VALUE: + D_ASSERT(field.children.size() == 1); + PopulateListFunctions(type, field.children[0]); + break; + case AggregateFieldKind::STRUCT: { + const auto &child_types = StructType::GetChildTypes(type); + D_ASSERT(child_types.size() == field.children.size()); + for (idx_t child_idx = 0; child_idx < field.children.size(); child_idx++) { + PopulateListFunctions(child_types[child_idx].second, field.children[child_idx]); + } + break; + } + default: + break; + } + } static idx_t GetPhysicalSize(const LogicalType &type) { if (type.id() != LogicalTypeId::STRUCT) { @@ -116,13 +284,45 @@ struct AggregateStateField { } idx_t size = 0; for (const auto &child : StructType::GetChildTypes(type)) { - idx_t child_size = GetPhysicalSize(child.second); - size = AlignValue(size, MinValue(child_size, 8)); - size += child_size; + size = AlignValue(size, GetPhysicalAlignment(child.second)); + size += GetPhysicalSize(child.second); } return size; } + //! The C++ alignment of a state member described by a logical type, mirroring alignof of the corresponding + //! member in the actual state struct. The alignment is platform-dependent (e.g. string_t is 8-byte aligned on + //! 64-bit platforms but only 4-byte aligned on 32-bit Windows), so it must come from the actual C++ types. + static idx_t GetPhysicalAlignment(const LogicalType &type) { + if (type.id() == LogicalTypeId::STRUCT) { + idx_t alignment = 1; + for (const auto &child : StructType::GetChildTypes(type)) { + alignment = MaxValue(alignment, GetPhysicalAlignment(child.second)); + } + return alignment; + } + switch (type.InternalType()) { + case PhysicalType::VARCHAR: + return alignof(string_t); + case PhysicalType::INT64: + case PhysicalType::UINT64: + return alignof(int64_t); + case PhysicalType::DOUBLE: + return alignof(double); + case PhysicalType::INT128: + return alignof(hugeint_t); + case PhysicalType::UINT128: + return alignof(uhugeint_t); + case PhysicalType::INTERVAL: + return alignof(interval_t); + case PhysicalType::LIST: + return alignof(list_entry_t); + default: + // the remaining primitive types are at most 4 bytes - their alignment equals their size + return MinValue(GetTypeIdSize(type.InternalType()), 8); + } + } + static void PopulateChildren(const LogicalType &type, AggregateStateField &field) { if (type.id() != LogicalTypeId::STRUCT) { return; @@ -131,9 +331,13 @@ struct AggregateStateField { idx_t offset = 0; for (auto &[name, child_type] : StructType::GetChildTypes(type)) { idx_t child_size = GetPhysicalSize(child_type); - offset = AlignValue(offset, MinValue(child_size, 8)); + offset = AlignValue(offset, GetPhysicalAlignment(child_type)); AggregateStateField child_field; child_field.field_offset = offset; + child_field.field_size = child_size; + child_field.field_alignment = GetPhysicalAlignment(child_type); + child_field.kind = + (child_type.id() == LogicalTypeId::STRUCT) ? AggregateFieldKind::STRUCT : AggregateFieldKind::PRIMITIVE; PopulateChildren(child_type, child_field); field.children.push_back(std::move(child_field)); offset += child_size; @@ -141,35 +345,9 @@ struct AggregateStateField { } }; -//! Populate one field's worth of AggregateStateField children from a C++ type T. -//! Advances `offset` by the physical size of T (including the is_set bool for OptionalStateType). +// Forward-declared so StructStateType::AppendChildren can call it before the full definition below. template -void PopulateFieldFromType(AggregateStateField &parent, idx_t &offset) { - AggregateStateField child; - if constexpr (IsOptionalStateType::value) { - using V = typename T::value_type; - constexpr idx_t alignment = MinValue(sizeof(V), 8); - offset = AlignValue(offset, alignment); - child.field_offset = offset; - child.is_optional = true; - parent.children.push_back(std::move(child)); - offset += sizeof(V) + sizeof(bool); - } else if constexpr (HasStructStateType::value) { - auto logical = FieldToLogicalType(); - idx_t sz = AggregateStateField::GetPhysicalSize(logical); - offset = AlignValue(offset, MinValue(sz, 8)); - child.field_offset = offset; - AggregateStateField::PopulateChildren(logical, child); - parent.children.push_back(std::move(child)); - offset += sz; - } else { - constexpr idx_t alignment = MinValue(sizeof(T), 8); - offset = AlignValue(offset, alignment); - child.field_offset = offset; - parent.children.push_back(std::move(child)); - offset += sizeof(T); - } -} +AggregateStateField BuildStateField(); //! Describes a struct-typed aggregate state layout. Intended for use as a nested type inside an aggregate STATE struct: //! static constexpr const char *STATE_NAMES[] = {"field_a", "field_b"}; @@ -180,17 +358,26 @@ void PopulateFieldFromType(AggregateStateField &parent, idx_t &offset) { //! Names are passed at call time (STATE::STATE_NAMES) rather than as template arguments. template struct StructStateType { - static LogicalType GetLogicalType(const char *const *names) { + static LogicalType GetLogicalType(const char *const *names, const StateLayoutTypeInfo &info) { child_list_t children; idx_t i = 0; - (children.emplace_back(names[i++], FieldToLogicalType()), ...); + (children.emplace_back(names[i++], FieldToLogicalType(info)), ...); return LogicalType::STRUCT(std::move(children)); } - //! Populate field children using compile-time type knowledge, correctly handling OptionalStateType. - static void PopulateField(AggregateStateField &field) { - idx_t offset = 0; - (PopulateFieldFromType(field, offset), ...); + //! Appends one child field for type T into field.children, advancing offset by the field's physical size. + template + static void AppendChildField(AggregateStateField &field, idx_t &offset) { + auto child = BuildStateField(); + offset = AlignValue(offset, child.GetAlignment()); + child.ShiftBase(offset); + offset += child.field_size; + field.children.push_back(std::move(child)); + } + + //! Populate field.children for all member types, computing offsets from sizes. + static void AppendChildren(AggregateStateField &field, idx_t &offset) { + (AppendChildField(field, offset), ...); } }; @@ -200,19 +387,95 @@ struct IsStructStateType : std::false_type {}; template struct IsStructStateType> : std::true_type {}; +//! Build an AggregateStateField for a compile-time state type T, with field_offset=0. +//! field_size is always set to the physical byte size of T's data (see kind docs for details). +//! +//! Composable rules: +//! - OptionalStateType → OPTIONAL_VALUE: is_set at field_offset=V.field_size, wraps BuildStateField() +//! - StateSortKey → SORT_KEY: field_size=sizeof(string_t) +//! - StructStateType → STRUCT: children built via AppendChildren, field_size=total child data size +//! - anything else → PRIMITIVE: field_size=sizeof(T) +template +AggregateStateField BuildStateField() { + AggregateStateField field; + if constexpr (IsOptionalStateType::value) { + using V = typename T::value_type; + field.kind = AggregateFieldKind::OPTIONAL_VALUE; + auto value_child = BuildStateField(); + value_child.field_offset = 0; + field.field_offset = value_child.field_size; // is_set follows the value data + field.field_size = value_child.field_size + sizeof(bool); + field.children.push_back(std::move(value_child)); + } else if constexpr (IsStateSortKeyType::value) { + field.kind = AggregateFieldKind::SORT_KEY; + field.sort_key_order = T::order_type; + field.field_size = sizeof(string_t); + field.field_alignment = alignof(string_t); + } else if constexpr (IsStateTypedValueType::value) { + // stored as a plain value - only the logical type is resolved at bind time + field.field_size = sizeof(typename T::PHYSICAL_TYPE); + field.field_alignment = alignof(typename T::PHYSICAL_TYPE); + } else if constexpr (IsStateListType::value) { + field.kind = AggregateFieldKind::LIST; + field.field_size = sizeof(LinkedList); + field.field_alignment = alignof(LinkedList); + } else if constexpr (IsStructStateType::value) { + // T is StructStateType — the phantom descriptor type itself + field.kind = AggregateFieldKind::STRUCT; + idx_t offset = 0; + T::AppendChildren(field, offset); + field.field_size = offset; // total physical size of all members + for (auto &child : field.children) { + field.field_alignment = MaxValue(field.field_alignment, child.GetAlignment()); + } + } else if constexpr (HasStructStateType::value) { + // T is a concrete C++ struct that declares STATE_TYPE = StructStateType<...> + field.kind = AggregateFieldKind::STRUCT; + idx_t offset = 0; + T::STATE_TYPE::AppendChildren(field, offset); + field.field_size = sizeof(T); + field.field_alignment = alignof(T); + } else { + // PRIMITIVE + field.field_size = sizeof(T); + field.field_alignment = alignof(T); + } + return field; +} + //! Top-level description of an aggregate state for export/import purposes. //! Returned by the aggregate_get_state_type_t callback registered via SetStructStateExport. //! -//! - Primitive state (e.g. int64_t for count): type=BIGINT, field.children empty, field.is_optional=false -//! - Optional state (e.g. OptionalStateType): type=BOOLEAN, field.is_optional=true, field.children empty -//! - Struct state: type=STRUCT(...), field.children fully populated via StructStateType::PopulateField -//! total_state_size is the aligned size of the full state (stride between consecutive states in a buffer). +//! - Primitive state (e.g. int64_t for count): field.kind=PRIMITIVE, field.field_offset=0, field.children empty. +//! - Optional primitive (e.g. OptionalStateType): field.kind=OPTIONAL_VALUE, +//! field.field_offset=sizeof(double) (is_set offset), field.children=[{kind=PRIMITIVE, field_offset=0}]. +//! - Optional struct: field.kind=OPTIONAL_VALUE, field.field_offset=struct_size (is_set offset), +//! field.children=[{kind=STRUCT, field_offset=0, children=[struct fields]}]. +//! - Non-optional struct: field.kind=STRUCT, field.field_offset=0, field.children=[struct fields]. +//! total_state_size is the aligned stride between consecutive states in a packed buffer. struct AggregateStateLayout { AggregateStateLayout() = default; AggregateStateLayout(LogicalType type_p, idx_t total_state_size_p, bool is_optional = false) : type(std::move(type_p)), total_state_size(total_state_size_p) { - field.is_optional = is_optional; - AggregateStateField::PopulateChildren(type, field); + if (is_optional) { + field.kind = AggregateFieldKind::OPTIONAL_VALUE; + field.field_offset = AggregateStateField::GetPhysicalSize(type); // is_set after the value + field.field_size = field.field_offset + sizeof(bool); + AggregateStateField value_child; + value_child.field_offset = 0; + value_child.field_size = field.field_offset; + value_child.kind = + (type.id() == LogicalTypeId::STRUCT) ? AggregateFieldKind::STRUCT : AggregateFieldKind::PRIMITIVE; + AggregateStateField::PopulateChildren(type, value_child); + field.children.push_back(std::move(value_child)); + } else if (type.id() == LogicalTypeId::STRUCT) { + field.kind = AggregateFieldKind::STRUCT; + AggregateStateField::PopulateChildren(type, field); + field.field_size = AggregateStateField::GetPhysicalSize(type); + } else { + field.field_size = AggregateStateField::GetPhysicalSize(type); + } + // else: field.kind = PRIMITIVE (default), field.children empty } LogicalType type; diff --git a/src/duckdb/src/include/duckdb/function/cast/cast_function_set.hpp b/src/duckdb/src/include/duckdb/function/cast/cast_function_set.hpp index afdba020f..eded57863 100644 --- a/src/duckdb/src/include/duckdb/function/cast/cast_function_set.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/cast_function_set.hpp @@ -9,6 +9,7 @@ #pragma once #include "duckdb/function/cast/default_casts.hpp" +#include "duckdb/function/combine_types_rule.hpp" namespace duckdb { struct MapCastInfo; @@ -64,9 +65,21 @@ class CastFunctionSet { DUCKDB_API void RegisterCastFunction(const LogicalType &source, const LogicalType &target, bind_cast_function_t bind, int64_t implicit_cast_cost = -1); + //! Register a combine rule for LogicalType::TryGetMaxLogicalType, consulted before previously registered rules + //! and the built-in rules + DUCKDB_API void RegisterCombineTypesRule(CombineTypesRule rule); + //! Run `rules` against (left, right); the first matching rule wins and writes its outcome to `success`. + //! Returns false if no rule matched. + static bool TryCombineTypes(const vector &rules, LogicalTypeResolver &resolver, + const LogicalType &left, const LogicalType &right, LogicalType &result, bool &success); + //! Same, over this set's rules (registered + built-in) + bool TryCombineTypes(LogicalTypeResolver &resolver, const LogicalType &left, const LogicalType &right, + LogicalType &result, bool &success); + private: optional_ptr config; vector bind_functions; + vector combine_rules; //! If any custom cast functions have been defined using RegisterCastFunction, this holds the map optional_ptr map_info; diff --git a/src/duckdb/src/include/duckdb/function/combine_types_rule.hpp b/src/duckdb/src/include/duckdb/function/combine_types_rule.hpp new file mode 100644 index 000000000..9393caa4c --- /dev/null +++ b/src/duckdb/src/include/duckdb/function/combine_types_rule.hpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/combine_types_rule.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/types.hpp" + +namespace duckdb { +class ClientContext; + +class LogicalTypeResolver { +public: + explicit LogicalTypeResolver(optional_ptr context_p) : context(context_p) { + } + virtual ~LogicalTypeResolver() = default; + + virtual bool Operation(const LogicalType &left, const LogicalType &right, LogicalType &result) = 0; + +public: + optional_ptr context; +}; + +typedef bool (*combine_types_rule_function_t)(LogicalTypeResolver &resolver, const LogicalType &left, + const LogicalType &right, LogicalType &result); + +struct CombineTypesRule { + bool (*matches)(const LogicalType &left, const LogicalType &right); // order-insensitive in (left, right) + combine_types_rule_function_t function; +}; + +//! The built-in combine rules, used to seed CastFunctionSet and as the fallback when no context is available +const vector &DefaultCombineTypesRules(); + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/copy_function.hpp b/src/duckdb/src/include/duckdb/function/copy_function.hpp index 4dd20df2b..31c672963 100644 --- a/src/duckdb/src/include/duckdb/function/copy_function.hpp +++ b/src/duckdb/src/include/duckdb/function/copy_function.hpp @@ -13,6 +13,7 @@ #include "duckdb/parser/parsed_data/copy_info.hpp" #include "duckdb/parser/statement/copy_statement.hpp" #include "duckdb/common/enums/copy_option_mode.hpp" +#include "duckdb/common/insertion_order_preserving_map.hpp" #include "duckdb/common/optional_ptr.hpp" namespace duckdb { @@ -190,7 +191,9 @@ struct CopyFunctionFileStatistics { idx_t row_count = 0; idx_t file_size_bytes = 0; Value footer_size_bytes; - // map of column name -> statistics name -> statistics value + //! Format-specific statistics (e.g. row_group_count for Parquet) + InsertionOrderPreservingMap extra_info; + //! map of column name -> statistics name -> statistics value case_insensitive_map_t> column_statistics; }; diff --git a/src/duckdb/src/include/duckdb/function/function.hpp b/src/duckdb/src/include/duckdb/function/function.hpp index dd9ab0121..ad24c50ae 100644 --- a/src/duckdb/src/include/duckdb/function/function.hpp +++ b/src/duckdb/src/include/duckdb/function/function.hpp @@ -96,6 +96,21 @@ struct TableFunctionData : public FunctionData { DUCKDB_API bool Equals(const FunctionData &other) const override; }; +struct FunctionLocalState { + DUCKDB_API virtual ~FunctionLocalState(); + + template + TARGET &Cast() { + DynamicCastCheck(this); + return reinterpret_cast(*this); + } + template + const TARGET &Cast() const { + DynamicCastCheck(this); + return reinterpret_cast(*this); + } +}; + struct FunctionParameters { vector values; named_parameter_map_t named_parameters; diff --git a/src/duckdb/src/include/duckdb/function/scalar/variant_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/variant_functions.hpp index 0d33059f9..85dd82ea3 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/variant_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/variant_functions.hpp @@ -15,6 +15,16 @@ namespace duckdb { +struct VariantArrayLengthFun { + static constexpr const char *Name = "variant_array_length"; + static constexpr const char *Parameters = "input_variant::VARIANT\001input_variant::VARIANT,path::VARCHAR\001input_variant::VARIANT,path::VARCHAR[]"; + static constexpr const char *Description = "Returns the number of elements in the variant, or `0` if not an array.\001Returns the number of elements in the array at the specified path in the variant, or `0` if not an array.\001Returns the number of elements in the array for each specified path in the variant, or `0` if not an array."; + static constexpr const char *Example = "variant_array_length(['duck', 'goose']::VARIANT)\001variant_array_length({'a': ['duck', 'goose']}::VARIANT, 'a')\001variant_array_length({'a': 1, 'b': ['duck', 'goose']}::VARIANT, ['a', 'b'])"; + static constexpr const char *Categories = "variant\001variant\001variant"; + + static ScalarFunctionSet GetFunctions(); +}; + struct VariantExistsFun { static constexpr const char *Name = "variant_exists"; static constexpr const char *Parameters = "input_variant::VARIANT,path::VARCHAR\001input_variant::VARIANT,path::VARCHAR[]"; diff --git a/src/duckdb/src/include/duckdb/function/scalar/variant_path_function.hpp b/src/duckdb/src/include/duckdb/function/scalar/variant_path_function.hpp new file mode 100644 index 000000000..49899c0d8 --- /dev/null +++ b/src/duckdb/src/include/duckdb/function/scalar/variant_path_function.hpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/scalar/variant_path_function.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/function/scalar/variant_utils.hpp" + +namespace duckdb { + +struct VariantPathFunction { + //! Executes scalar VARIANT functions that accept an optional constant path argument. + //! The function may be called as f(VARIANT), f(VARIANT, VARCHAR) or f(VARIANT, VARCHAR[]). + //! `collect_fn` is run once for each requested path and produces an intermediate result. + //! `write_fn` writes one row from that intermediate result. + template + static void Execute(DataChunk &input, const ExpressionState &state, Vector &result, + const COLLECT_FUNCTION &collect_fn, const WRITE_FUNCTION &write_fn) { + D_ASSERT(input.ColumnCount() == 1 || input.ColumnCount() == 2); + const auto count = input.size(); + const auto &variant_vec = input.data[0]; + + if (input.ColumnCount() == 2) { + const auto &path = input.data[1]; + D_ASSERT(path.GetVectorType() == VectorType::CONSTANT_VECTOR); + (void)path; + } + + auto &func_expr = state.expr.Cast(); + auto &info = func_expr.BindInfo()->Cast(); + auto n_columns = input.ColumnCount(); + + if (n_columns == 1) { + ExecuteUnary(variant_vec, {}, result, count, collect_fn, write_fn); + return; + } + + D_ASSERT(n_columns == 2); + const auto &path_type_id = input.data[1].GetType().id(); + + if (path_type_id == LogicalTypeId::VARCHAR) { + ExecuteUnary(variant_vec, info.paths[0], result, count, collect_fn, write_fn); + return; + } + if (path_type_id == LogicalTypeId::LIST) { + ExecuteMany(variant_vec, info.paths, result, count, collect_fn, write_fn); + return; + } + } + +private: + //! Executes a single path and writes RESULT_TYPE per input row. + template + static void ExecuteUnary(const Vector &variant_vec, const vector &components, Vector &result, + const idx_t count, const COLLECT_FUNCTION &collect_fn, const WRITE_FUNCTION &write_fn) { + RecursiveUnifiedVectorFormat source_format; + Vector::RecursiveToUnifiedFormat(variant_vec, source_format); + const UnifiedVariantVectorData variant(source_format); + + const COLLECTED_TYPE collected = collect_fn(variant, components, count); + + result.Initialize(VectorDataInitialization::UNINITIALIZED, count); + auto row_writer = FlatVector::Writer(result, count); + + for (idx_t row_idx = 0; row_idx < count; row_idx++) { + if (!variant.RowIsValid(row_idx)) { + row_writer.WriteNull(); + continue; + } + + write_fn(variant, row_writer, collected, row_idx); + } + } + + //! Executes a list of paths and writes LIST per input row. + template + static void ExecuteMany(const Vector &variant_vec, const vector> &paths, + Vector &result, const idx_t count, const COLLECT_FUNCTION &collect_fn, + const WRITE_FUNCTION &write_fn) { + vector collected_by_path; + collected_by_path.reserve(paths.size()); + + RecursiveUnifiedVectorFormat source_format; + Vector::RecursiveToUnifiedFormat(variant_vec, source_format); + const UnifiedVariantVectorData variant(source_format); + + for (const auto &path : paths) { + collected_by_path.push_back(collect_fn(variant, path, count)); + } + + result.Initialize(VectorDataInitialization::UNINITIALIZED, count); + auto result_writer = FlatVector::Writer>(result, count); + + for (idx_t row_idx = 0; row_idx < count; row_idx++) { + if (!variant.RowIsValid(row_idx)) { + result_writer.WriteNull(); + continue; + } + + auto row_writer = result_writer.WriteList(paths.size()); + + idx_t path_idx = 0; + for (auto &path_writer : row_writer) { + write_fn(variant, path_writer, collected_by_path[path_idx], row_idx); + path_idx++; + } + } + } +}; +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/scalar/variant_utils.hpp b/src/duckdb/src/include/duckdb/function/scalar/variant_utils.hpp index 78181dd6e..fe5f98b86 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/variant_utils.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/variant_utils.hpp @@ -113,14 +113,6 @@ struct VariantPathSelection { }; struct VariantUtils { - using unary_path_function_t = void (*)(const Vector &, const vector &, Vector &, idx_t); - using many_path_function_t = void (*)(const Vector &, const vector> &, Vector &, - idx_t); - - //! Generic dispatcher for function execution, used by functions that take an (optional) path(s) - DUCKDB_API static void ExecutePathFunction(DataChunk &input, const ExpressionState &state, Vector &result, - const unary_path_function_t &unary_fn, - const many_path_function_t &many_fn); DUCKDB_API static bool IsNestedType(const UnifiedVariantVectorData &variant, idx_t row, uint32_t value_index); DUCKDB_API static VariantDecimalData DecodeDecimalData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t value_index); diff --git a/src/duckdb/src/include/duckdb/function/scalar_function.hpp b/src/duckdb/src/include/duckdb/function/scalar_function.hpp index d40363fb2..fd57c9e59 100644 --- a/src/duckdb/src/include/duckdb/function/scalar_function.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar_function.hpp @@ -20,21 +20,6 @@ #include "duckdb/common/enums/filter_propagate_result.hpp" namespace duckdb { -struct FunctionLocalState { - DUCKDB_API virtual ~FunctionLocalState(); - - template - TARGET &Cast() { - DynamicCastCheck(this); - return reinterpret_cast(*this); - } - template - const TARGET &Cast() const { - DynamicCastCheck(this); - return reinterpret_cast(*this); - } -}; - struct ScalarFunctionInfo { DUCKDB_API virtual ~ScalarFunctionInfo(); diff --git a/src/duckdb/src/include/duckdb/main/client_config.hpp b/src/duckdb/src/include/duckdb/main/client_config.hpp index 6f5e0102d..e05d0df27 100644 --- a/src/duckdb/src/include/duckdb/main/client_config.hpp +++ b/src/duckdb/src/include/duckdb/main/client_config.hpp @@ -12,7 +12,6 @@ #include "duckdb/common/common.hpp" #include "duckdb/common/optional_idx.hpp" #include "duckdb/common/enums/output_type.hpp" -#include "duckdb/common/enums/profiler_format.hpp" #include "duckdb/common/progress_bar/progress_bar.hpp" #include "duckdb/common/types/value.hpp" #include "duckdb/parser/expression/lambda_expression.hpp" @@ -31,20 +30,18 @@ typedef std::function(ClientContext &context, Prepa struct ClientConfig { //! If the query profiler is enabled or not. bool enable_profiler = false; - //! If detailed query profiling is enabled - bool enable_detailed_profiling = false; //! The format to print query profiling information in (default: query_tree), if enabled. - ProfilerPrintFormat profiler_print_format = ProfilerPrintFormat::QUERY_TREE; + //! This is the profiler format name passed to QueryProfiler::CreateProfiler. + string profiler_print_format = "query_tree"; //! The file to save query profiling information to, instead of printing it to the console //! (empty = print to console) string profiler_save_location; //! Glob patterns for tracked_metrics (controls which metrics are gathered and displayed). //! Default "*" means all metrics are tracked. vector tracked_metrics = {"*"}; - - //! Allows suppressing profiler output, even if enabled. We turn on the profiler on all test runs but don't want - //! to output anything - bool emit_profiler_output = true; + //! Settings that are passed to the renderer of the profiler output (e.g. 'maximum_render_width' for the text + //! renderer). Settings that are not recognized by the active renderer are ignored. + unordered_map profiling_renderer_settings; //! system-wide progress bar disable. const char *system_progress_bar_disable_reason = nullptr; diff --git a/src/duckdb/src/include/duckdb/main/connection.hpp b/src/duckdb/src/include/duckdb/main/connection.hpp index 32b3f6b92..644f5cfa8 100644 --- a/src/duckdb/src/include/duckdb/main/connection.hpp +++ b/src/duckdb/src/include/duckdb/main/connection.hpp @@ -8,7 +8,7 @@ #pragma once -#include "duckdb/common/enums/profiler_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" #include "duckdb/common/serializer/buffered_file_writer.hpp" #include "duckdb/common/winapi.hpp" #include "duckdb/main/materialized_query_result.hpp" @@ -50,8 +50,9 @@ class Connection { shared_ptr context; public: - //! Returns query profiling information for the current query - DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE); + //! Returns query profiling information for the current query, formatted according to the given ProfilerPrintFormat + //! (e.g. ProfilerPrintFormat::JSON()). ProfilerPrintFormat::Default() uses the configured default profiler format. + DUCKDB_API string GetProfilingInformation(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()); //! Interrupt execution of the current query DUCKDB_API void Interrupt(); diff --git a/src/duckdb/src/include/duckdb/main/extension/extension_loader.hpp b/src/duckdb/src/include/duckdb/main/extension/extension_loader.hpp index 4c21b3c0a..a775d181f 100644 --- a/src/duckdb/src/include/duckdb/main/extension/extension_loader.hpp +++ b/src/duckdb/src/include/duckdb/main/extension/extension_loader.hpp @@ -11,7 +11,7 @@ #include "duckdb/common/constants.hpp" #include "duckdb/function/cast/cast_function_set.hpp" #include "duckdb/function/function_set.hpp" -#include "duckdb/main/metric_info.hpp" +#include "duckdb/main/profiler/metric_info.hpp" #include "duckdb/main/secret/secret.hpp" #include "duckdb/parser/parsed_data/create_type_info.hpp" #include "duckdb/main/extension_install_info.hpp" @@ -129,6 +129,9 @@ class ExtensionLoader { DUCKDB_API void RegisterCastFunction(const LogicalType &source, const LogicalType &target, BoundCastInfo function, int64_t implicit_cast_cost = -1); + //! Registers a rule for combining two types in implicit type resolution (LogicalType::TryGetMaxLogicalType) + DUCKDB_API void RegisterCombineTypesRule(CombineTypesRule rule); + //! Registers a custom metric so it appears in duckdb_available_metrics. DUCKDB_API void RegisterMetric(MetricInfo info); diff --git a/src/duckdb/src/include/duckdb/main/gathered_metrics.hpp b/src/duckdb/src/include/duckdb/main/profiler/gathered_metrics.hpp similarity index 95% rename from src/duckdb/src/include/duckdb/main/gathered_metrics.hpp rename to src/duckdb/src/include/duckdb/main/profiler/gathered_metrics.hpp index 5c70f3e22..d9319c0db 100644 --- a/src/duckdb/src/include/duckdb/main/gathered_metrics.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/gathered_metrics.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/gathered_metrics.hpp +// duckdb/main/profiler/gathered_metrics.hpp // // //===----------------------------------------------------------------------===// @@ -10,14 +10,13 @@ #include "duckdb/common/common.hpp" #include "duckdb/common/enums/output_type.hpp" -#include "duckdb/common/enums/profiler_format.hpp" #include "duckdb/common/progress_bar/progress_bar.hpp" #include "duckdb/common/types/value.hpp" #include "duckdb/common/unordered_set.hpp" #include "duckdb/common/constants.hpp" #include "duckdb/common/enums/metric_type.hpp" #include "duckdb/common/set.hpp" -#include "duckdb/main/metrics.hpp" +#include "duckdb/main/profiler/metrics.hpp" namespace duckdb_yyjson { struct yyjson_mut_doc; diff --git a/src/duckdb/src/include/duckdb/main/metric_info.hpp b/src/duckdb/src/include/duckdb/main/profiler/metric_info.hpp similarity index 92% rename from src/duckdb/src/include/duckdb/main/metric_info.hpp rename to src/duckdb/src/include/duckdb/main/profiler/metric_info.hpp index 1ce4d2e25..f596e78da 100644 --- a/src/duckdb/src/include/duckdb/main/metric_info.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/metric_info.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/metric_info.hpp +// duckdb/main/profiler/metric_info.hpp // // //===----------------------------------------------------------------------===// diff --git a/src/duckdb/src/include/duckdb/main/metrics.hpp b/src/duckdb/src/include/duckdb/main/profiler/metrics.hpp similarity index 99% rename from src/duckdb/src/include/duckdb/main/metrics.hpp rename to src/duckdb/src/include/duckdb/main/profiler/metrics.hpp index ff7e56928..2ae7eee32 100644 --- a/src/duckdb/src/include/duckdb/main/metrics.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/metrics.hpp @@ -2,7 +2,7 @@ // // DuckDB // -// duckdb/main/metrics.hpp +// duckdb/main/profiler/metrics.hpp // // This file is automatically generated by scripts/generate_metrics.py // Do not edit this file manually, your changes will be overwritten diff --git a/src/duckdb/src/include/duckdb/main/metrics_manager.hpp b/src/duckdb/src/include/duckdb/main/profiler/metrics_manager.hpp similarity index 93% rename from src/duckdb/src/include/duckdb/main/metrics_manager.hpp rename to src/duckdb/src/include/duckdb/main/profiler/metrics_manager.hpp index e6994e9cb..a3ed9f72c 100644 --- a/src/duckdb/src/include/duckdb/main/metrics_manager.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/metrics_manager.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/metrics_manager.hpp +// duckdb/main/profiler/metrics_manager.hpp // // //===----------------------------------------------------------------------===// @@ -11,7 +11,7 @@ #include "duckdb/common/common.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/main/metric_info.hpp" +#include "duckdb/main/profiler/metric_info.hpp" namespace duckdb { diff --git a/src/duckdb/src/include/duckdb/main/profiler/profiler_print_format.hpp b/src/duckdb/src/include/duckdb/main/profiler/profiler_print_format.hpp new file mode 100644 index 000000000..fcf9452b4 --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/profiler/profiler_print_format.hpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/profiler/profiler_print_format.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/string.hpp" + +namespace duckdb { + +//! ProfilerPrintFormat identifies an EXPLAIN / profiler output format by name (e.g. "json", "text"). +struct ProfilerPrintFormat { + ProfilerPrintFormat() : format("default") { + } + explicit ProfilerPrintFormat(string format) : format(std::move(format)) { + } + + //! Named formats. + static ProfilerPrintFormat Default() { + return ProfilerPrintFormat("default"); + } + static ProfilerPrintFormat Text() { + return ProfilerPrintFormat("text"); + } + static ProfilerPrintFormat JSON() { + return ProfilerPrintFormat("json"); + } + static ProfilerPrintFormat HTML() { + return ProfilerPrintFormat("html"); + } + static ProfilerPrintFormat Graphviz() { + return ProfilerPrintFormat("graphviz"); + } + static ProfilerPrintFormat YAML() { + return ProfilerPrintFormat("yaml"); + } + static ProfilerPrintFormat Mermaid() { + return ProfilerPrintFormat("mermaid"); + } + + //! Resolve a (case-insensitive) format name against the registry, returning its canonical form. Throws + //! InvalidInputException listing the valid format names when the name is not recognized. + static ProfilerPrintFormat FromString(const string &name); + + bool operator==(const ProfilerPrintFormat &other) const { + return format == other.format; + } + bool operator!=(const ProfilerPrintFormat &other) const { + return !(*this == other); + } + + //! The canonical (lowercase) format name. + const string &ToString() const { + return format; + } + + string format; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/profiling_node.hpp b/src/duckdb/src/include/duckdb/main/profiler/profiling_node.hpp similarity index 97% rename from src/duckdb/src/include/duckdb/main/profiling_node.hpp rename to src/duckdb/src/include/duckdb/main/profiler/profiling_node.hpp index 872fe2bf1..3f87bb04d 100644 --- a/src/duckdb/src/include/duckdb/main/profiling_node.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/profiling_node.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/profiling_node.hpp +// duckdb/main/profiler/profiling_node.hpp // // //===----------------------------------------------------------------------===// @@ -9,7 +9,7 @@ #pragma once #include "duckdb/common/common.hpp" -#include "duckdb/main/gathered_metrics.hpp" +#include "duckdb/main/profiler/gathered_metrics.hpp" namespace duckdb { diff --git a/src/duckdb/src/include/duckdb/main/profiling_utils.hpp b/src/duckdb/src/include/duckdb/main/profiler/profiling_utils.hpp similarity index 97% rename from src/duckdb/src/include/duckdb/main/profiling_utils.hpp rename to src/duckdb/src/include/duckdb/main/profiler/profiling_utils.hpp index 6dd5c7fea..b76db4bcd 100644 --- a/src/duckdb/src/include/duckdb/main/profiling_utils.hpp +++ b/src/duckdb/src/include/duckdb/main/profiler/profiling_utils.hpp @@ -2,7 +2,7 @@ // // DuckDB // -// duckdb/main/profiling_utils.hpp +// duckdb/main/profiler/profiling_utils.hpp // //===----------------------------------------------------------------------===// @@ -10,8 +10,8 @@ #include "duckdb/common/enums/metric_type.hpp" #include "duckdb/common/exception.hpp" -#include "duckdb/main/gathered_metrics.hpp" -#include "duckdb/main/profiling_node.hpp" +#include "duckdb/main/profiler/gathered_metrics.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" #include "duckdb/common/profiler.hpp" namespace duckdb_yyjson { diff --git a/src/duckdb/src/include/duckdb/main/query_profiler.hpp b/src/duckdb/src/include/duckdb/main/query_profiler.hpp index 95fd94aab..41ae07c0b 100644 --- a/src/duckdb/src/include/duckdb/main/query_profiler.hpp +++ b/src/duckdb/src/include/duckdb/main/query_profiler.hpp @@ -11,10 +11,10 @@ #include "duckdb/common/common.hpp" #include "duckdb/common/deque.hpp" #include "duckdb/common/enums/metric_type.hpp" -#include "duckdb/common/enums/profiler_format.hpp" -#include "duckdb/common/enums/explain_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/numeric_utils.hpp" +#include "duckdb/common/optional_ptr.hpp" #include "duckdb/common/pair.hpp" #include "duckdb/common/profiler.hpp" #include "duckdb/common/reference_map.hpp" @@ -24,8 +24,8 @@ #include "duckdb/common/winapi.hpp" #include "duckdb/execution/expression_executor_state.hpp" #include "duckdb/execution/physical_operator.hpp" -#include "duckdb/main/profiling_node.hpp" -#include "duckdb/main/profiling_utils.hpp" +#include "duckdb/main/profiler/profiling_node.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" namespace duckdb { @@ -33,6 +33,7 @@ class ClientContext; class ExpressionExecutor; class ProfilingNode; class PhysicalOperator; +class TreeRenderer; class SQLStatement; struct MetricsTimer; class OperatorProfiler; @@ -83,8 +84,13 @@ class QueryProfiler { public: DUCKDB_API bool IsEnabled() const; - DUCKDB_API bool IsDetailedEnabled() const; - DUCKDB_API ProfilerPrintFormat GetPrintFormat(ExplainFormat format = ExplainFormat::DEFAULT) const; + //! Create the TreeRenderer for the given profiler format name (e.g. "json", "query_tree"). Returns nullptr for the + //! "no_output" format, and throws if the format name is not recognized. + DUCKDB_API unique_ptr CreateProfiler(const string &name) const; + //! Returns the renderer to use for the given ProfilerPrintFormat, taking the configured default format into + //! account. + DUCKDB_API unique_ptr + GetRenderer(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()) const; DUCKDB_API bool PrintOptimizerOutput() const; DUCKDB_API string GetSaveLocation() const; @@ -133,10 +139,15 @@ class QueryProfiler { DUCKDB_API void QueryTreeToStream(std::ostream &str) const; DUCKDB_API void Print(); - //! return the printed as a string. Unlike ToString, which is always formatted as a string, - //! the return value is formatted based on the current print format (see GetPrintFormat()). - DUCKDB_API string ToString(ExplainFormat format = ExplainFormat::DEFAULT) const; - DUCKDB_API string ToString(ProfilerPrintFormat format) const; + //! Render the profiler output as a string, formatted based on the given ProfilerPrintFormat (or the configured + //! default profiler format when ProfilerPrintFormat::Default is passed). + DUCKDB_API string ToString(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()) const; + //! Render the profiler output for the given profiler format name (e.g. "json", "query_tree"), handling the + //! profiling-disabled and no-output cases. + DUCKDB_API string ToString(const string &profiler_format_name) const; + //! Render the profiling node tree using the given renderer. Returns an empty string when there is no tree to + //! render. Called by TreeRenderer::RenderProfiler for the formats that render the node tree directly. + DUCKDB_API string RenderProfilingNodeTree(TreeRenderer &renderer) const; // Sanitize a Value::MAP static Value JSONSanitize(const Value &input); @@ -156,7 +167,8 @@ class QueryProfiler { private: unique_ptr CreateTree(const PhysicalOperator &root, const idx_t depth = 0); void Render(const ProfilingNode &node, std::ostream &str) const; - string RenderDisabledMessage(ProfilerPrintFormat format) const; + //! Render the profiler output via the given renderer (nullptr renders nothing), handling the disabled case. + string RenderProfilerOutput(optional_ptr renderer) const; private: ClientContext &context; @@ -202,7 +214,6 @@ class QueryProfiler { //! Check whether or not an operator type requires query profiling. If none of the ops in a query require profiling //! no profiling information is output. bool OperatorRequiresProfiling(const PhysicalOperatorType op_type); - ExplainFormat GetExplainFormat(ProfilerPrintFormat format) const; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/relation.hpp b/src/duckdb/src/include/duckdb/main/relation.hpp index 6e7267dbc..127e48ee0 100644 --- a/src/duckdb/src/include/duckdb/main/relation.hpp +++ b/src/duckdb/src/include/duckdb/main/relation.hpp @@ -99,7 +99,7 @@ class Relation : public enable_shared_from_this { //! Explain the query plan of this relation DUCKDB_API unique_ptr Explain(ExplainType type = ExplainType::EXPLAIN_STANDARD, - ExplainFormat explain_format = ExplainFormat::DEFAULT); + const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()); DUCKDB_API virtual unique_ptr GetTableRef(); virtual bool IsReadOnly() { diff --git a/src/duckdb/src/include/duckdb/main/relation/explain_relation.hpp b/src/duckdb/src/include/duckdb/main/relation/explain_relation.hpp index 96be08d8f..c2d35fb7a 100644 --- a/src/duckdb/src/include/duckdb/main/relation/explain_relation.hpp +++ b/src/duckdb/src/include/duckdb/main/relation/explain_relation.hpp @@ -15,12 +15,12 @@ namespace duckdb { class ExplainRelation : public Relation { public: explicit ExplainRelation(shared_ptr child, ExplainType type = ExplainType::EXPLAIN_STANDARD, - ExplainFormat format = ExplainFormat::DEFAULT); + const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()); shared_ptr child; vector columns; ExplainType type; - ExplainFormat format; + ProfilerPrintFormat format; public: BoundStatement Bind(Binder &binder) override; diff --git a/src/duckdb/src/include/duckdb/main/settings.hpp b/src/duckdb/src/include/duckdb/main/settings.hpp index a29a7b470..167a62fe9 100644 --- a/src/duckdb/src/include/duckdb/main/settings.hpp +++ b/src/duckdb/src/include/duckdb/main/settings.hpp @@ -1649,37 +1649,49 @@ struct ProduceArrowStringViewSetting { static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; -struct ProfileOutputSetting { +struct ProfilingCoverageSetting { using RETURN_TYPE = string; - static constexpr const char *Name = "profile_output"; - static constexpr const char *Description = - "The file to which profile output should be saved, or empty to print to the terminal"; + static constexpr const char *Name = "profiling_coverage"; + static constexpr const char *Description = "The profiling coverage (SELECT or ALL)"; static constexpr const char *InputType = "VARCHAR"; static void SetLocal(ClientContext &context, const Value ¶meter); static void ResetLocal(ClientContext &context); static Value GetSetting(const ClientContext &context); }; -struct ProfilingCoverageSetting { +struct ProfilingModeSetting { using RETURN_TYPE = string; - static constexpr const char *Name = "profiling_coverage"; - static constexpr const char *Description = "The profiling coverage (SELECT or ALL)"; + static constexpr const char *Name = "profiling_mode"; + static constexpr const char *Description = "DEPRECATED: Sets the profiling mode"; static constexpr const char *InputType = "VARCHAR"; static void SetLocal(ClientContext &context, const Value ¶meter); static void ResetLocal(ClientContext &context); static Value GetSetting(const ClientContext &context); }; -struct ProfilingModeSetting { +struct ProfilingOutputSetting { using RETURN_TYPE = string; - static constexpr const char *Name = "profiling_mode"; - static constexpr const char *Description = "The profiling mode (STANDARD or DETAILED)"; + static constexpr const char *Name = "profiling_output"; + static constexpr const char *Description = + "The file to which profile output should be saved, or empty to print to the terminal"; static constexpr const char *InputType = "VARCHAR"; static void SetLocal(ClientContext &context, const Value ¶meter); static void ResetLocal(ClientContext &context); static Value GetSetting(const ClientContext &context); }; +struct ProfilingRendererSettingsSetting { + using RETURN_TYPE = unordered_map; + static constexpr const char *Name = "profiling_renderer_settings"; + static constexpr const char *Description = + "A map of settings passed to the renderer of the profiler output (e.g. {'max_extra_lines': 100}) - settings " + "not recognized by the active renderer are ignored"; + static constexpr const char *InputType = "MAP(VARCHAR, VARCHAR)"; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(const ClientContext &context); +}; + struct ProgressBarTimeSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "progress_bar_time"; diff --git a/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp b/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp index a528fa1cd..6b05ae024 100644 --- a/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp @@ -63,6 +63,15 @@ class UnnestRewriter { //! Find delim joins that contain an UNNEST void FindCandidates(unique_ptr &root, unique_ptr &op, vector>> &candidates); + //! Rewrite materialized CTEs that encode duplicate eliminated UNNEST joins + bool RewriteCTECandidates(unique_ptr &root, unique_ptr &op, + UnnestRewriterPlanUpdater &updater); + //! Rewrite a materialized CTE that encodes one duplicate eliminated UNNEST join + bool RewriteCTECandidate(unique_ptr &root, unique_ptr &candidate, + UnnestRewriterPlanUpdater &updater); + //! Rewrite a materialized CTE where the deduplicated input has already been inlined + bool RewriteInlineCTEDedupCandidate(unique_ptr &root, unique_ptr &candidate, + UnnestRewriterPlanUpdater &updater); //! Rewrite a delim join that contains an UNNEST bool RewriteCandidate(unique_ptr &candidate); //! Update the bindings of the RHS sequence of LOGICAL_PROJECTION(s) diff --git a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp index 50507a22f..a98a8ba50 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp @@ -724,7 +724,9 @@ const char INLINED_PEG_GRAMMAR[] = { "FunctionIdentifier <- CatalogReservedSchemaFunctionName / SchemaReservedFunctionName / FunctionName\n" "CatalogReservedSchemaFunctionName <- CatalogQualification ReservedSchemaQualification? ReservedFunctionName\n" "SchemaReservedFunctionName <- SchemaQualification ReservedFunctionName\n" - "DistinctOrAll <- 'DISTINCT' / 'ALL'\n" + "DistinctOrAll <- DistinctKeyword / AllKeyword\n" + "DistinctKeyword <- 'DISTINCT'\n" + "AllKeyword <- 'ALL'\n" "ExportClause <- 'EXPORT_STATE'\n" "WithinGroupClause <- 'WITHIN' 'GROUP' Parens(OrderByClause)\n" "FilterClause <- 'FILTER' Parens('WHERE'? Expression)\n" @@ -1221,8 +1223,10 @@ const char INLINED_PEG_GRAMMAR[] = { "CreateSchemaStmt <- 'SCHEMA' IfNotExists? QualifiedName\n" "SelectStatement <- SelectStatementInternal\n" "SelectStatementInternal <- WithClause? SelectSetOpChain ResultModifiers?\n" - "SelectSetOpChain <- IntersectChain (SetopClause IntersectChain)*\n" - "IntersectChain <- SelectAtom (SetIntersectClause SelectAtom)*\n" + "SelectSetOpChain <- IntersectChain SelectSetOpChainTail*\n" + "SelectSetOpChainTail <- SetopClause IntersectChain\n" + "IntersectChain <- SelectAtom IntersectChainTail*\n" + "IntersectChainTail <- SetIntersectClause SelectAtom\n" "SetIntersectClause <- 'INTERSECT' DistinctOrAll?\n" "SelectAtom <- SelectParens / SelectStatementType\n" "SelectParens <- Parens(SelectStatementInternal)\n" @@ -1244,8 +1248,9 @@ const char INLINED_PEG_GRAMMAR[] = { "SelectFromClause <- SelectClause FromClause?\n" "FromSelectClause <- FromClause SelectClause?\n" "WithStatement <- ColIdOrString InsertColumnList? UsingKey? 'AS' Materialized? CTEBody\n" - "CTEBody <- Parens(CTEBodyContent)\n" - "CTEBodyContent <- SelectStatementInternal / Statement\n" + "CTEBody <- CTESelectBody / CTEDMLBody\n" + "CTESelectBody <- Parens(SelectStatementInternal)\n" + "CTEDMLBody <- Parens(Statement)\n" "UsingKey <- 'USING' 'KEY' Parens(TargetList)\n" "Materialized <- 'NOT'? 'MATERIALIZED'\n" "WithClause <- 'WITH' Recursive? List(WithStatement)\n" @@ -1265,16 +1270,20 @@ const char INLINED_PEG_GRAMMAR[] = { "ValuesRef <- ValuesClause TableAlias?\n" "ParensTableRef <- TableAliasColon? Parens(TableRef) TableAlias? SampleClause?\n" "JoinOrPivot <- JoinClause / TablePivotClause / TableUnpivotClause\n" - "TablePivotClause <- 'PIVOT' Parens(TargetList 'FOR' PivotValueList+ PivotGroupByList?) TableAlias?\n" + "TablePivotClause <- 'PIVOT' Parens(TablePivotClauseBody) TableAlias?\n" + "TablePivotClauseBody <- TargetList 'FOR' PivotValueList+ PivotGroupByList?\n" "PivotGroupByList <- 'GROUP' 'BY' List(ColIdOrString)\n" - "TableUnpivotClause <- 'UNPIVOT' IncludeOrExcludeNulls? Parens(UnpivotHeader 'FOR' UnpivotValueList+) TableAlias?\n" + "TableUnpivotClause <- 'UNPIVOT' IncludeOrExcludeNulls? Parens(TableUnpivotClauseBody) TableAlias?\n" + "TableUnpivotClauseBody <- UnpivotHeader 'FOR' UnpivotValueList+\n" "PivotHeader <- BaseExpression\n" - "PivotValueList <- PivotHeader 'IN' (Identifier / PivotTargetList)\n" + "PivotValueList <- PivotHeader 'IN' PivotValueTarget\n" + "PivotValueTarget <- Identifier / PivotTargetList\n" "UnpivotValueList <- UnpivotHeader 'IN' UnpivotTargetList\n" "PivotTargetList <- Parens(TargetList)\n" "UnpivotTargetList <- Parens(TargetList)\n" "Lateral <- 'LATERAL'\n" - "BaseTableName <- CatalogReservedSchemaTable / SchemaReservedTable / TableName\n" + "BaseTableName <- CatalogReservedSchemaTable / SchemaReservedTable / UnqualifiedBaseTableName\n" + "UnqualifiedBaseTableName <- TableName\n" "SchemaReservedTable <- SchemaQualification ReservedTableName\n" "CatalogReservedSchemaTable <- CatalogQualification ReservedSchemaQualification ReservedTableName\n" "TableFunction <- TableFunctionLateralOpt / TableFunctionAliasColon\n" @@ -1283,7 +1292,9 @@ const char INLINED_PEG_GRAMMAR[] = { "WithOrdinality <- 'WITH' 'ORDINALITY'\n" "QualifiedTableFunction <- CatalogQualification? SchemaQualification? TableFunctionName\n" "TableFunctionArguments <- Parens(List(FunctionArgument)?)\n" - "FunctionArgument <- NamedParameter / Expression\n" + "FunctionArgument <- NamedFunctionArgument / PositionalFunctionArgument\n" + "NamedFunctionArgument <- NamedParameter\n" + "PositionalFunctionArgument <- Expression\n" "NamedParameter <- TypeFuncName Type? NamedParameterAssignment Expression\n" "NamedParameterAssignment <- ':=' / '=>'\n" "TableAlias <- TableAliasAs / TableAliasWithoutAs\n" @@ -1291,9 +1302,12 @@ const char INLINED_PEG_GRAMMAR[] = { "TableAliasWithoutAs <- Identifier ColumnAliases?\n" "AtClause <- 'AT' Parens(AtSpecifier)\n" "AtSpecifier <- AtUnit '=>' Expression\n" - "AtUnit <- 'VERSION' / 'TIMESTAMP'\n" + "AtUnit <- VersionAtUnit / TimestampAtUnit\n" + "VersionAtUnit <- 'VERSION'\n" + "TimestampAtUnit <- 'TIMESTAMP'\n" "JoinClause <- RegularJoinClause / JoinWithoutOnClause\n" - "RegularJoinClause <- 'ASOF'? JoinType? 'JOIN' TableRef JoinQualifier\n" + "RegularJoinClause <- Asof? JoinType? 'JOIN' TableRef JoinQualifier\n" + "Asof <- 'ASOF'\n" "JoinWithoutOnClause <- JoinPrefix 'JOIN' TableRef\n" "JoinQualifier <- OnClause / UsingClause\n" "OnClause <- 'ON' Expression\n" @@ -1334,11 +1348,14 @@ const char INLINED_PEG_GRAMMAR[] = { "GroupByExpressions <- GroupByList / GroupByAll\n" "GroupByAll <- 'ALL'\n" "GroupByList <- List(GroupByExpression)\n" - "GroupByExpression <- EmptyGroupingItem / CubeOrRollupClause / GroupingSetsClause / Expression\n" + "GroupByExpression <- EmptyGroupingItem / CubeOrRollupClause / GroupingSetsClause / GroupByBaseExpression\n" + "GroupByBaseExpression <- Expression\n" "EmptyGroupingItem <- '(' ')'\n" "CubeOrRollupClause <- CubeOrRollup Parens(List(Expression)?)\n" - "CubeOrRollup <- 'CUBE' / 'ROLLUP'\n" - "GroupingSetsClause <- 'GROUPING' 'SETS' Parens(GroupByList)\n" + "CubeOrRollup <- CubeKeyword / RollupKeyword\n" + "CubeKeyword <- 'CUBE'\n" + "RollupKeyword <- 'ROLLUP'\n" + "GroupingSetsClause <- 'GROUPING' 'SETS' Parens(List(GroupByExpression))\n" "SubqueryReference <- Parens(SelectStatementInternal)\n" "OrderByExpression <- Expression DescOrAsc? NullsFirstOrLast?\n" "DescOrAsc <- DescendingOrder / AscendingOrder\n" diff --git a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp index 57d8aa48f..b0539c264 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp @@ -32,6 +32,8 @@ #include "duckdb/parser/peg/ast/trigger_table_referencing_info.hpp" #include "duckdb/parser/peg/ast/window_frame.hpp" #include "duckdb/function/macro_function.hpp" +#include "duckdb/common/optional.hpp" +#include "duckdb/parser/query_node/set_operation_node.hpp" #include "duckdb/parser/parser_options.hpp" #include "duckdb/common/stack_checker.hpp" #include "duckdb/parser/expression/case_expression.hpp" @@ -62,6 +64,15 @@ struct MatcherToken; struct GroupingExpressionMap; class Matcher; +enum class GroupByExpressionInfoType : uint8_t { EXPRESSION, EMPTY, CUBE, ROLLUP, GROUPING_SETS }; + +struct GroupByExpressionInfo { + GroupByExpressionInfoType type = GroupByExpressionInfoType::EMPTY; + unique_ptr expression; + vector> expressions; + vector children; +}; + struct PEGTransformerState { explicit PEGTransformerState(const vector &tokens_p) : tokens(tokens_p), token_index(0) { } @@ -293,7 +304,7 @@ class PEGTransformerFactory { static unique_ptr ConvertNumberToValue(string val); static void AddGroupByExpression(unique_ptr expression, GroupingExpressionMap &map, GroupByNode &result, vector &result_set); - static vector GroupByExpressionUnfolding(PEGTransformer &transformer, ParseResult &group_by_expr, + static vector GroupByExpressionUnfolding(GroupByExpressionInfo &group_by_expr, GroupingExpressionMap &map, GroupByNode &result); static unique_ptr VerifyLimitOffset(LimitPercentResult &limit, LimitPercentResult &offset); static unique_ptr ToRecursiveCTE(unique_ptr node, const Identifier &name, @@ -650,174 +661,18 @@ class PEGTransformerFactory { ParseResult &parse_result); // select.gram - static unique_ptr TransformSelectStatement(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSelectSetOpChain(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntersectChain(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectAtom(PEGTransformer &transformer, ParseResult &parse_result); - static SetOperationType TransformSetopType(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSetopClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSetIntersectClause(PEGTransformer &transformer, - ParseResult &parse_result); + static unique_ptr TransformSelectStatementInternalRule(PEGTransformer &transformer, + ParseResult &parse_result); static bool TransformDistinctOrAll(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectParens(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectStatementType(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOptionalParensSimpleSelect(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleSelectParens(PEGTransformer &transformer, - ParseResult &parse_result); + static bool TransformDistinctKeyword(PEGTransformer &transformer, ParseResult &parse_result); + static bool TransformAllKeyword(PEGTransformer &transformer, ParseResult &parse_result); static unique_ptr TransformSimpleSelect(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectFrom(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectFromClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformFromSelectClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformFromClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSelectClause(PEGTransformer &transformer, ParseResult &parse_result); - static DistinctClause TransformDistinctClause(PEGTransformer &transformer, ParseResult &parse_result); - static DistinctClause TransformDistinctOn(PEGTransformer &transformer, ParseResult &parse_result); - static vector> TransformDistinctOnTargets(PEGTransformer &transformer, - ParseResult &parse_result); - static DistinctClause TransformDistinctAll(PEGTransformer &transformer, ParseResult &parse_result); - static FunctionArgument TransformFunctionArgument(PEGTransformer &transformer, ParseResult &parse_result); - static MacroParameter TransformNamedParameter(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformTableFunctionArguments(PEGTransformer &transformer, - ParseResult &parse_result); - - static unique_ptr TransformBaseTableName(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSchemaReservedTable(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCatalogReservedSchemaTable(PEGTransformer &transformer, - ParseResult &parse_result); - QualifiedName TransformCatalogReservedSchemaIdentifierOrStringLiteral(PEGTransformer &transformer, - optional_ptr parse_result); - static QualifiedName TransformTableNameIdentifierOrStringLiteral(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformWhereClause(PEGTransformer &transformer, ParseResult &parse_result); - - static vector> TransformTargetList(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAliasedExpression(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExpressionAsCollabel(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColIdExpression(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExpressionOptIdentifier(PEGTransformer &transformer, - ParseResult &parse_result); - static TableAlias TransformTableAlias(PEGTransformer &transformer, ParseResult &parse_result); - static TableAlias TransformTableAliasAs(PEGTransformer &transformer, ParseResult &parse_result); - static TableAlias TransformTableAliasWithoutAs(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformColumnAliases(PEGTransformer &transformer, ParseResult &parse_result); - - static vector TransformOrderByClause(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformOrderByExpressions(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformOrderByExpressionList(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformOrderByAll(PEGTransformer &transformer, ParseResult &parse_result); - static OrderByNode TransformOrderByExpression(PEGTransformer &transformer, ParseResult &parse_result); - static OrderType TransformDescOrAsc(PEGTransformer &transformer, ParseResult &parse_result); - static OrderByNullType TransformNullsFirstOrLast(PEGTransformer &transformer, ParseResult &parse_result); static unique_ptr TransformTableRef(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformJoinOrPivot(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformJoinClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformRegularJoinClause(PEGTransformer &transformer, ParseResult &parse_result); - static JoinType TransformJoinType(PEGTransformer &transformer, ParseResult &parse_result); - static JoinQualifier TransformJoinQualifier(PEGTransformer &transformer, ParseResult &parse_result); - static JoinQualifier TransformOnClause(PEGTransformer &transformer, ParseResult &parse_result); - static JoinQualifier TransformUsingClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformJoinWithoutOnClause(PEGTransformer &transformer, ParseResult &parse_result); - static JoinPrefix TransformJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result); - static JoinPrefix TransformCrossJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result); - static JoinPrefix TransformNaturalJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result); - static JoinPrefix TransformPositionalJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformTableUnpivotClause(PEGTransformer &transformer, ParseResult &parse_result); - static PivotColumn TransformUnpivotValueList(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformUnpivotTargetList(PEGTransformer &transformer, ParseResult &parse_result); - - static unique_ptr TransformTablePivotClause(PEGTransformer &transformer, ParseResult &parse_result); - static PivotColumn TransformPivotValueList(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformPivotGroupByList(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformPivotHeader(PEGTransformer &transformer, ParseResult &parse_result); - static vector TransformPivotTargetList(PEGTransformer &transformer, ParseResult &parse_result); - - static unique_ptr TransformInnerTableRef(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformTableFunction(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformTableFunctionLateralOpt(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTableFunctionAliasColon(PEGTransformer &transformer, - ParseResult &parse_result); - static string TransformTableAliasColon(PEGTransformer &transformer, ParseResult &parse_result); - static QualifiedName TransformQualifiedTableFunction(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformTableSubquery(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSubqueryReference(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformBaseTableRef(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformParensTableRef(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformAtClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformAtSpecifier(PEGTransformer &transformer, ParseResult &parse_result); - static string TransformAtUnit(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformValuesRef(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformValuesClause(PEGTransformer &transformer, ParseResult &parse_result); - static vector> TransformValuesExpressions(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTableStatement(PEGTransformer &transformer, ParseResult &parse_result); - static vector> TransformResultModifiers(PEGTransformer &transformer, - ParseResult &parse_result); - - static unique_ptr TransformLimitOffset(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformOffsetLimitClause(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLimitOffsetClause(PEGTransformer &transformer, - ParseResult &parse_result); - static LimitPercentResult TransformLimitClause(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformLimitValue(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformLimitAll(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformLimitLiteralPercent(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformLimitExpression(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformOffsetClause(PEGTransformer &transformer, ParseResult &parse_result); - static LimitPercentResult TransformOffsetValue(PEGTransformer &transformer, ParseResult &parse_result); - static GroupByNode TransformGroupByClause(PEGTransformer &transformer, ParseResult &parse_result); - static GroupByNode TransformGroupByExpressions(PEGTransformer &transformer, ParseResult &parse_result); - static GroupByNode TransformGroupByAll(PEGTransformer &transformer, ParseResult &parse_result); - static GroupByNode TransformGroupByList(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformGroupByExpression(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformEmptyGroupingItem(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCubeOrRollupClause(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformGroupingSetsClause(PEGTransformer &transformer, - ParseResult &parse_result); - static string TransformCubeOrRollup(PEGTransformer &transformer, ParseResult &parse_result); static CommonTableExpressionMap TransformWithClause(PEGTransformer &transformer, ParseResult &parse_result); - static pair> TransformWithStatement(PEGTransformer &transformer, - ParseResult &parse_result); - static vector> TransformUsingKey(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCTEBody(PEGTransformer &transformer, ParseResult &parse_result); - static bool TransformMaterialized(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformHavingClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformQualifyClause(PEGTransformer &transformer, ParseResult &parse_result); - static vector> TransformWindowClause(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWindowDefinition(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSampleClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSampleEntry(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSampleEntryFunction(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSampleEntryCount(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSampleCount(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformSampleValue(PEGTransformer &transformer, ParseResult &parse_result); - static bool TransformSampleUnit(PEGTransformer &transformer, ParseResult &parse_result); - static pair TransformSampleProperties(PEGTransformer &transformer, - ParseResult &parse_result); - static optional_idx TransformSampleSeed(PEGTransformer &transformer, ParseResult &parse_result); - static SampleMethod TransformSampleFunction(PEGTransformer &transformer, ParseResult &parse_result); - static optional_idx TransformRepeatableSample(PEGTransformer &transformer, ParseResult &parse_result); - static string TransformIdentifierOrKeyword(PEGTransformer &transformer, ParseResult &parse_result); //===--------------------------------------------------------------------===// @@ -2481,6 +2336,557 @@ class PEGTransformerFactory { static unique_ptr TransformTypeListInternal(PEGTransformer &transformer, ParseResult &parse_result); static vector TransformTypeList(PEGTransformer &transformer, const vector &type); + static unique_ptr TransformSelectStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectStatement(PEGTransformer &transformer, + unique_ptr select_statement_internal); + static unique_ptr TransformSelectSetOpChainInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectSetOpChain( + PEGTransformer &transformer, unique_ptr intersect_chain, + optional, unique_ptr>>> select_set_op_chain_tail); + static unique_ptr TransformSelectSetOpChainTailInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static pair, unique_ptr> + TransformSelectSetOpChainTail(PEGTransformer &transformer, unique_ptr setop_clause, + unique_ptr intersect_chain); + static unique_ptr TransformIntersectChainInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformIntersectChain( + PEGTransformer &transformer, unique_ptr select_atom, + optional, unique_ptr>>> intersect_chain_tail); + static unique_ptr TransformIntersectChainTailInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static pair, unique_ptr> + TransformIntersectChainTail(PEGTransformer &transformer, unique_ptr set_intersect_clause, + unique_ptr select_atom); + static unique_ptr TransformSetIntersectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSetIntersectClause(PEGTransformer &transformer, + const optional &distinct_or_all); + static unique_ptr TransformSelectAtomInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectParensInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectParens(PEGTransformer &transformer, + unique_ptr select_statement_internal); + static unique_ptr TransformSetopClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSetopClause(PEGTransformer &transformer, + const SetOperationType &setop_type, + const optional &distinct_or_all, + const bool &has_result); + static unique_ptr TransformSetopTypeInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSetopUnionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static SetOperationType TransformSetopUnion(PEGTransformer &transformer); + static unique_ptr TransformSetopExceptInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static SetOperationType TransformSetopExcept(PEGTransformer &transformer); + static unique_ptr TransformSelectStatementTypeInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformResultModifiersInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> + TransformResultModifiers(PEGTransformer &transformer, optional> order_by_clause, + optional> limit_offset); + static unique_ptr TransformLimitOffsetInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformLimitOffsetClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformLimitOffsetClause(PEGTransformer &transformer, + LimitPercentResult limit_clause, + optional offset_clause); + static unique_ptr TransformOffsetLimitClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformOffsetLimitClause(PEGTransformer &transformer, + LimitPercentResult offset_clause, + optional limit_clause); + static unique_ptr TransformTableStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableStatement(PEGTransformer &transformer, + unique_ptr base_table_name); + static unique_ptr TransformOptionalParensSimpleSelectInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSimpleSelectParensInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSimpleSelectParens(PEGTransformer &transformer, + unique_ptr simple_select); + static unique_ptr TransformSelectFromInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectFromClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectFromClause(PEGTransformer &transformer, + unique_ptr select_clause, + optional> from_clause); + static unique_ptr TransformFromSelectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformFromSelectClause(PEGTransformer &transformer, + unique_ptr from_clause, + optional> select_clause); + static unique_ptr TransformWithStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static pair> + TransformWithStatement(PEGTransformer &transformer, const Identifier &col_id_or_string, + const optional> &insert_column_list, + optional>> using_key, const optional &materialized, + unique_ptr cte_body); + static unique_ptr TransformCTEBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCTESelectBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCTESelectBody(PEGTransformer &transformer, + unique_ptr select_statement_internal); + static unique_ptr TransformCTEDMLBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCTEDMLBody(PEGTransformer &transformer, unique_ptr statement); + static unique_ptr TransformUsingKeyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> TransformUsingKey(PEGTransformer &transformer, + vector> target_list); + static unique_ptr TransformMaterializedInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformMaterialized(PEGTransformer &transformer, const bool &has_result); + static unique_ptr TransformSelectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSelectClause(PEGTransformer &transformer, + optional distinct_clause, + optional>> target_list); + static unique_ptr TransformTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> + TransformTargetList(PEGTransformer &transformer, vector> aliased_expression); + static unique_ptr TransformColumnAliasesInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformColumnAliases(PEGTransformer &transformer, + const vector &col_id_or_string); + static unique_ptr TransformDistinctClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformDistinctAllInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static DistinctClause TransformDistinctAll(PEGTransformer &transformer); + static unique_ptr TransformDistinctOnInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static DistinctClause TransformDistinctOn(PEGTransformer &transformer, + optional>> distinct_on_targets); + static unique_ptr TransformDistinctOnTargetsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> + TransformDistinctOnTargets(PEGTransformer &transformer, vector> expression); + static unique_ptr TransformInnerTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableSubqueryInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableSubquery(PEGTransformer &transformer, const optional &lateral, + unique_ptr subquery_reference, + const optional &table_alias); + static unique_ptr TransformBaseTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr + TransformBaseTableRef(PEGTransformer &transformer, const optional &table_alias_colon, + unique_ptr base_table_name, const optional &table_alias, + optional> at_clause, optional> sample_clause); + static unique_ptr TransformTableAliasColonInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static Identifier TransformTableAliasColon(PEGTransformer &transformer, const Identifier &col_id_or_string); + static unique_ptr TransformValuesRefInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformValuesRef(PEGTransformer &transformer, + unique_ptr values_clause, + const optional &table_alias); + static unique_ptr TransformParensTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformParensTableRef(PEGTransformer &transformer, + const optional &table_alias_colon, + unique_ptr table_ref, + const optional &table_alias, + optional> sample_clause); + static unique_ptr TransformJoinOrPivotInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTablePivotClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTablePivotClause(PEGTransformer &transformer, + unique_ptr table_pivot_clause_body, + const optional &table_alias); + static unique_ptr TransformTablePivotClauseBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTablePivotClauseBody(PEGTransformer &transformer, + vector> target_list, + vector pivot_value_list, + const optional> &pivot_group_by_list); + static unique_ptr TransformPivotGroupByListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformPivotGroupByList(PEGTransformer &transformer, + const vector &col_id_or_string); + static unique_ptr TransformTableUnpivotClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableUnpivotClause(PEGTransformer &transformer, + const optional &include_or_exclude_nulls, + unique_ptr table_unpivot_clause_body, + const optional &table_alias); + static unique_ptr TransformTableUnpivotClauseBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableUnpivotClauseBody(PEGTransformer &transformer, + const vector &unpivot_header, + vector unpivot_value_list); + static unique_ptr TransformPivotHeaderInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformPivotHeader(PEGTransformer &transformer, + unique_ptr base_expression); + static unique_ptr TransformPivotValueListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static PivotColumn TransformPivotValueList(PEGTransformer &transformer, unique_ptr pivot_header, + PivotColumn pivot_value_target); + static unique_ptr TransformPivotValueTargetInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static PivotColumn TransformPivotValueTarget(PEGTransformer &transformer, ParseResult &choice_result); + static unique_ptr TransformUnpivotValueListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static PivotColumn TransformUnpivotValueList(PEGTransformer &transformer, const vector &unpivot_header, + vector unpivot_target_list); + static unique_ptr TransformPivotTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformPivotTargetList(PEGTransformer &transformer, + vector> target_list); + static unique_ptr TransformUnpivotTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformUnpivotTargetList(PEGTransformer &transformer, + vector> target_list); + static unique_ptr TransformLateralInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformLateral(PEGTransformer &transformer); + static unique_ptr TransformBaseTableNameInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformUnqualifiedBaseTableNameInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformUnqualifiedBaseTableName(PEGTransformer &transformer, + const Identifier &table_name); + static unique_ptr TransformSchemaReservedTableInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSchemaReservedTable(PEGTransformer &transformer, + const Identifier &schema_qualification, + const Identifier &reserved_table_name); + static unique_ptr TransformCatalogReservedSchemaTableInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCatalogReservedSchemaTable(PEGTransformer &transformer, + const Identifier &catalog_qualification, + const Identifier &reserved_schema_qualification, + const Identifier &reserved_table_name); + static unique_ptr TransformTableFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableFunctionLateralOptInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableFunctionLateralOpt(PEGTransformer &transformer, + const optional &lateral, + const QualifiedName &qualified_table_function, + vector table_function_arguments, + const optional &with_ordinality, + const optional &table_alias); + static unique_ptr TransformTableFunctionAliasColonInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableFunctionAliasColon(PEGTransformer &transformer, + const Identifier &table_alias_colon, + const QualifiedName &qualified_table_function, + vector table_function_arguments, + const optional &with_ordinality, + optional> sample_clause); + static unique_ptr TransformWithOrdinalityInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformWithOrdinality(PEGTransformer &transformer); + static unique_ptr TransformQualifiedTableFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static QualifiedName TransformQualifiedTableFunction(PEGTransformer &transformer, + const optional &catalog_qualification, + const optional &schema_qualification, + const Identifier &table_function_name); + static unique_ptr TransformTableFunctionArgumentsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector + TransformTableFunctionArguments(PEGTransformer &transformer, optional> function_argument); + static unique_ptr TransformFunctionArgumentInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformNamedFunctionArgumentInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static FunctionArgument TransformNamedFunctionArgument(PEGTransformer &transformer, MacroParameter named_parameter); + static unique_ptr TransformPositionalFunctionArgumentInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static FunctionArgument TransformPositionalFunctionArgument(PEGTransformer &transformer, + unique_ptr expression); + static unique_ptr TransformNamedParameterInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static MacroParameter TransformNamedParameter(PEGTransformer &transformer, const Identifier &type_func_name, + const optional &type, + unique_ptr expression); + static unique_ptr TransformTableAliasInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformTableAliasAsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static TableAlias TransformTableAliasAs(PEGTransformer &transformer, + const QualifiedName &identifier_or_string_literal, + const optional> &column_aliases); + static unique_ptr TransformTableAliasWithoutAsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static TableAlias TransformTableAliasWithoutAs(PEGTransformer &transformer, const Identifier &identifier, + const optional> &column_aliases); + static unique_ptr TransformAtClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformAtClause(PEGTransformer &transformer, unique_ptr at_specifier); + static unique_ptr TransformAtSpecifierInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformAtSpecifier(PEGTransformer &transformer, const string &at_unit, + unique_ptr expression); + static unique_ptr TransformAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformVersionAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static string TransformVersionAtUnit(PEGTransformer &transformer); + static unique_ptr TransformTimestampAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static string TransformTimestampAtUnit(PEGTransformer &transformer); + static unique_ptr TransformJoinClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformRegularJoinClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformRegularJoinClause(PEGTransformer &transformer, const optional &asof, + const optional &join_type, + unique_ptr table_ref, + JoinQualifier join_qualifier); + static unique_ptr TransformAsofInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformAsof(PEGTransformer &transformer); + static unique_ptr TransformJoinWithoutOnClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformJoinWithoutOnClause(PEGTransformer &transformer, const JoinPrefix &join_prefix, + unique_ptr table_ref); + static unique_ptr TransformJoinQualifierInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformOnClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinQualifier TransformOnClause(PEGTransformer &transformer, unique_ptr expression); + static unique_ptr TransformUsingClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinQualifier TransformUsingClause(PEGTransformer &transformer, const vector &column_name); + static unique_ptr TransformJoinTypeInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCrossJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinPrefix TransformCrossJoinPrefix(PEGTransformer &transformer); + static unique_ptr TransformNaturalJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinPrefix TransformNaturalJoinPrefix(PEGTransformer &transformer, const optional &join_type); + static unique_ptr TransformPositionalJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinPrefix TransformPositionalJoinPrefix(PEGTransformer &transformer); + static unique_ptr TransformFullJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformFullJoin(PEGTransformer &transformer, const bool &has_result); + static unique_ptr TransformLeftJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformLeftJoin(PEGTransformer &transformer, const bool &has_result); + static unique_ptr TransformRightJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformRightJoin(PEGTransformer &transformer, const bool &has_result); + static unique_ptr TransformSemiJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformSemiJoin(PEGTransformer &transformer); + static unique_ptr TransformAntiJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformAntiJoin(PEGTransformer &transformer); + static unique_ptr TransformInnerJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static JoinType TransformInnerJoin(PEGTransformer &transformer); + static unique_ptr TransformFromClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformFromClause(PEGTransformer &transformer, + vector> table_ref); + static unique_ptr TransformWhereClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformWhereClause(PEGTransformer &transformer, + unique_ptr expression); + static unique_ptr TransformGroupByClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByNode TransformGroupByClause(PEGTransformer &transformer, GroupByNode group_by_expressions); + static unique_ptr TransformHavingClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformHavingClause(PEGTransformer &transformer, + unique_ptr expression); + static unique_ptr TransformQualifyClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformQualifyClause(PEGTransformer &transformer, + unique_ptr expression); + static unique_ptr TransformSampleClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSampleClause(PEGTransformer &transformer, + unique_ptr sample_entry); + static unique_ptr TransformWindowClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> + TransformWindowClause(PEGTransformer &transformer, vector> window_definition); + static unique_ptr TransformSampleEntryInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSampleEntryCountInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr + TransformSampleEntryCount(PEGTransformer &transformer, unique_ptr sample_count, + const optional> &sample_properties); + static unique_ptr TransformSampleEntryFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSampleEntryFunction(PEGTransformer &transformer, + const optional &sample_function, + unique_ptr sample_count, + const optional &repeatable_sample); + static unique_ptr TransformSampleFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static SampleMethod TransformSampleFunction(PEGTransformer &transformer, const Identifier &col_id); + static unique_ptr TransformSamplePropertiesInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static pair TransformSampleProperties(PEGTransformer &transformer, + const Identifier &col_id, + const optional &sample_seed); + static unique_ptr TransformRepeatableSampleInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static optional_idx TransformRepeatableSample(PEGTransformer &transformer, const optional_idx &sample_seed); + static unique_ptr TransformSampleSeedInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static optional_idx TransformSampleSeed(PEGTransformer &transformer, unique_ptr number_literal); + static unique_ptr TransformSampleCountInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSampleCount(PEGTransformer &transformer, + unique_ptr sample_value, + const optional &sample_unit); + static unique_ptr TransformSampleValueInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSampleUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSamplePercentageInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformSamplePercentage(PEGTransformer &transformer); + static unique_ptr TransformSampleRowsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static bool TransformSampleRows(PEGTransformer &transformer); + static unique_ptr TransformGroupByExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformGroupByAllInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByNode TransformGroupByAll(PEGTransformer &transformer); + static unique_ptr TransformGroupByListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByNode TransformGroupByList(PEGTransformer &transformer, + vector group_by_expression); + static unique_ptr TransformGroupByExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformGroupByBaseExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByExpressionInfo TransformGroupByBaseExpression(PEGTransformer &transformer, + unique_ptr expression); + static unique_ptr TransformEmptyGroupingItemInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByExpressionInfo TransformEmptyGroupingItem(PEGTransformer &transformer); + static unique_ptr TransformCubeOrRollupClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByExpressionInfo TransformCubeOrRollupClause(PEGTransformer &transformer, const string &cube_or_rollup, + optional>> expression); + static unique_ptr TransformCubeOrRollupInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformCubeKeywordInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static string TransformCubeKeyword(PEGTransformer &transformer); + static unique_ptr TransformRollupKeywordInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static string TransformRollupKeyword(PEGTransformer &transformer); + static unique_ptr TransformGroupingSetsClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static GroupByExpressionInfo TransformGroupingSetsClause(PEGTransformer &transformer, + vector group_by_expression); + static unique_ptr TransformSubqueryReferenceInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformSubqueryReference(PEGTransformer &transformer, + unique_ptr select_statement_internal); + static unique_ptr TransformOrderByExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static OrderByNode TransformOrderByExpression(PEGTransformer &transformer, unique_ptr expression, + const optional &desc_or_asc, + const optional &nulls_first_or_last); + static unique_ptr TransformDescOrAscInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformDescendingOrderInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static OrderType TransformDescendingOrder(PEGTransformer &transformer); + static unique_ptr TransformAscendingOrderInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static OrderType TransformAscendingOrder(PEGTransformer &transformer); + static unique_ptr TransformNullsFirstOrLastInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformNullsFirstInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static OrderByNullType TransformNullsFirst(PEGTransformer &transformer); + static unique_ptr TransformNullsLastInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static OrderByNullType TransformNullsLast(PEGTransformer &transformer); + static unique_ptr TransformOrderByClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformOrderByClause(PEGTransformer &transformer, + vector order_by_expressions); + static unique_ptr TransformOrderByExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformOrderByExpressionListInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformOrderByExpressionList(PEGTransformer &transformer, + vector order_by_expression); + static unique_ptr TransformOrderByAllInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector TransformOrderByAll(PEGTransformer &transformer, const optional &desc_or_asc, + const optional &nulls_first_or_last); + static unique_ptr TransformLimitClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformLimitClause(PEGTransformer &transformer, LimitPercentResult limit_value); + static unique_ptr TransformOffsetClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformOffsetClause(PEGTransformer &transformer, LimitPercentResult offset_value); + static unique_ptr TransformOffsetValueInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformOffsetValue(PEGTransformer &transformer, unique_ptr expression, + const bool &has_result); + static unique_ptr TransformLimitValueInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformLimitAllInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformLimitAll(PEGTransformer &transformer); + static unique_ptr TransformLimitLiteralPercentInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformLimitLiteralPercent(PEGTransformer &transformer, + unique_ptr number_literal); + static unique_ptr TransformLimitExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static LimitPercentResult TransformLimitExpression(PEGTransformer &transformer, + unique_ptr expression, const bool &has_result); + static unique_ptr TransformAliasedExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformColIdExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformColIdExpression(PEGTransformer &transformer, const Identifier &col_id, + unique_ptr expression); + static unique_ptr TransformExpressionAsCollabelInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformExpressionAsCollabel(PEGTransformer &transformer, + unique_ptr expression, + const Identifier &col_label_or_string); + static unique_ptr TransformExpressionOptIdentifierInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr TransformExpressionOptIdentifier(PEGTransformer &transformer, + unique_ptr expression, + const optional &identifier); + static unique_ptr TransformValuesClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static unique_ptr + TransformValuesClause(PEGTransformer &transformer, vector>> values_expressions); + static unique_ptr TransformValuesExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result); + static vector> + TransformValuesExpressions(PEGTransformer &transformer, vector> expression); static unique_ptr TransformSetStatementInternal(PEGTransformer &transformer, ParseResult &parse_result); static unique_ptr TransformSetStatement(PEGTransformer &transformer, diff --git a/src/duckdb/src/include/duckdb/parser/statement/explain_statement.hpp b/src/duckdb/src/include/duckdb/parser/statement/explain_statement.hpp index 0ab5acec8..fcc9423de 100644 --- a/src/duckdb/src/include/duckdb/parser/statement/explain_statement.hpp +++ b/src/duckdb/src/include/duckdb/parser/statement/explain_statement.hpp @@ -9,7 +9,7 @@ #pragma once #include "duckdb/parser/sql_statement.hpp" -#include "duckdb/common/enums/explain_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" namespace duckdb { @@ -21,11 +21,11 @@ class ExplainStatement : public SQLStatement { public: explicit ExplainStatement(unique_ptr stmt, ExplainType explain_type = ExplainType::EXPLAIN_STANDARD, - ExplainFormat explain_format = ExplainFormat::DEFAULT); + const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()); unique_ptr stmt; ExplainType explain_type; - ExplainFormat explain_format = ExplainFormat::DEFAULT; + ProfilerPrintFormat format = ProfilerPrintFormat::Default(); protected: ExplainStatement(const ExplainStatement &other); diff --git a/src/duckdb/src/include/duckdb/planner/logical_operator.hpp b/src/duckdb/src/include/duckdb/planner/logical_operator.hpp index 9835b1cb8..55d35f717 100644 --- a/src/duckdb/src/include/duckdb/planner/logical_operator.hpp +++ b/src/duckdb/src/include/duckdb/planner/logical_operator.hpp @@ -11,7 +11,7 @@ #include "duckdb/catalog/catalog.hpp" #include "duckdb/common/common.hpp" #include "duckdb/common/enums/logical_operator_type.hpp" -#include "duckdb/common/enums/explain_format.hpp" +#include "duckdb/main/profiler/profiler_print_format.hpp" #include "duckdb/planner/column_binding.hpp" #include "duckdb/planner/expression.hpp" #include "duckdb/planner/logical_operator_visitor.hpp" @@ -64,7 +64,7 @@ class LogicalOperator { virtual string GetName() const; virtual InsertionOrderPreservingMap ParamsToString() const; - virtual string ToString(ExplainFormat format = ExplainFormat::DEFAULT) const; + virtual string ToString(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()) const; DUCKDB_API void Print(); //! Debug method: verify that the integrity of expressions & child nodes are maintained virtual void Verify(ClientContext &context); diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp index 284618595..338261103 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp @@ -21,10 +21,10 @@ class LogicalExplain : public LogicalOperator { static constexpr const LogicalOperatorType TYPE = LogicalOperatorType::LOGICAL_EXPLAIN; public: - LogicalExplain(unique_ptr plan, ExplainType explain_type, ExplainFormat explain_format); + LogicalExplain(unique_ptr plan, ExplainType explain_type, const ProfilerPrintFormat &format); ExplainType explain_type; - ExplainFormat explain_format; + ProfilerPrintFormat format; string physical_plan; string logical_plan_unopt; string logical_plan_opt; diff --git a/src/duckdb/src/main/client_context.cpp b/src/duckdb/src/main/client_context.cpp index 5029ef641..8ac6dfd7c 100644 --- a/src/duckdb/src/main/client_context.cpp +++ b/src/duckdb/src/main/client_context.cpp @@ -1290,7 +1290,6 @@ void ClientContext::EnableProfiling() { auto lock = LockContext(); auto &client_config = ClientConfig::GetConfig(*this); client_config.enable_profiler = true; - client_config.emit_profiler_output = true; } void ClientContext::DisableProfiling() { diff --git a/src/duckdb/src/main/config.cpp b/src/duckdb/src/main/config.cpp index e5761b0f8..2f5ace035 100644 --- a/src/duckdb/src/main/config.cpp +++ b/src/duckdb/src/main/config.cpp @@ -207,9 +207,10 @@ static const ConfigurationOption internal_options[] = { DUCKDB_SETTING(PreserveIdentifierCaseSetting), DUCKDB_SETTING(PreserveInsertionOrderSetting), DUCKDB_SETTING(ProduceArrowStringViewSetting), - DUCKDB_LOCAL(ProfileOutputSetting), DUCKDB_LOCAL(ProfilingCoverageSetting), DUCKDB_LOCAL(ProfilingModeSetting), + DUCKDB_LOCAL(ProfilingOutputSetting), + DUCKDB_LOCAL(ProfilingRendererSettingsSetting), DUCKDB_LOCAL(ProgressBarTimeSetting), DUCKDB_SETTING(ScalarSubqueryErrorOnMultipleRowsSetting), DUCKDB_SETTING(SchedulerProcessPartialSetting), @@ -239,10 +240,10 @@ static const ConfigurationAlias setting_aliases[] = {DUCKDB_SETTING_ALIAS("confi DUCKDB_SETTING_ALIAS("custom_profiling_settings", 28), DUCKDB_SETTING_ALIAS("memory_limit", 120), DUCKDB_SETTING_ALIAS("null_order", 55), - DUCKDB_SETTING_ALIAS("profiling_output", 141), - DUCKDB_SETTING_ALIAS("user", 158), + DUCKDB_SETTING_ALIAS("profile_output", 143), + DUCKDB_SETTING_ALIAS("user", 159), DUCKDB_SETTING_ALIAS("wal_autocheckpoint", 27), - DUCKDB_SETTING_ALIAS("worker_threads", 156), + DUCKDB_SETTING_ALIAS("worker_threads", 157), FINAL_ALIAS}; vector DBConfig::GetOptions() { diff --git a/src/duckdb/src/main/connection.cpp b/src/duckdb/src/main/connection.cpp index 29b856211..c4f17a23b 100644 --- a/src/duckdb/src/main/connection.cpp +++ b/src/duckdb/src/main/connection.cpp @@ -46,9 +46,8 @@ Connection::~Connection() { ConnectionManager::Get(*context->db).RemoveConnection(*context); } -string Connection::GetProfilingInformation(ProfilerPrintFormat format) { - auto &profiler = QueryProfiler::Get(*context); - return profiler.ToString(format); +string Connection::GetProfilingInformation(const ProfilerPrintFormat &format) { + return QueryProfiler::Get(*context).ToString(format); } void Connection::Interrupt() { diff --git a/src/duckdb/src/main/database.cpp b/src/duckdb/src/main/database.cpp index b5daa611f..89b59f868 100644 --- a/src/duckdb/src/main/database.cpp +++ b/src/duckdb/src/main/database.cpp @@ -1,5 +1,5 @@ #include "duckdb/main/database.hpp" -#include "duckdb/main/metrics_manager.hpp" +#include "duckdb/main/profiler/metrics_manager.hpp" #include "duckdb/parser/peg/matcher.hpp" #include "duckdb/catalog/catalog.hpp" diff --git a/src/duckdb/src/main/extension/extension_loader.cpp b/src/duckdb/src/main/extension/extension_loader.cpp index d8f6ffc9f..b7210336e 100644 --- a/src/duckdb/src/main/extension/extension_loader.cpp +++ b/src/duckdb/src/main/extension/extension_loader.cpp @@ -19,7 +19,7 @@ #include "duckdb/main/config.hpp" #include "duckdb/main/secret/secret_manager.hpp" #include "duckdb/main/database.hpp" -#include "duckdb/main/metrics_manager.hpp" +#include "duckdb/main/profiler/metrics_manager.hpp" #include "duckdb/main/extension_callback_manager.hpp" #include "re2/re2.h" @@ -367,6 +367,10 @@ void ExtensionLoader::RegisterCastFunction(const LogicalType &source, const Logi casts.RegisterCastFunction(source, target, std::move(function), implicit_cast_cost); } +void ExtensionLoader::RegisterCombineTypesRule(CombineTypesRule rule) { + DBConfig::GetConfig(db).GetCastFunctions().RegisterCombineTypesRule(rule); +} + void ExtensionLoader::RegisterMetric(MetricInfo info) { MetricsManager::Get(db).RegisterMetric(std::move(info)); } diff --git a/src/duckdb/src/main/gathered_metrics.cpp b/src/duckdb/src/main/profiler/gathered_metrics.cpp similarity index 97% rename from src/duckdb/src/main/gathered_metrics.cpp rename to src/duckdb/src/main/profiler/gathered_metrics.cpp index e0adc0831..dc8f5f98f 100644 --- a/src/duckdb/src/main/gathered_metrics.cpp +++ b/src/duckdb/src/main/profiler/gathered_metrics.cpp @@ -1,9 +1,9 @@ -#include "duckdb/main/gathered_metrics.hpp" +#include "duckdb/main/profiler/gathered_metrics.hpp" #include "duckdb/common/file_system.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/function/scalar/string_common.hpp" -#include "duckdb/main/profiling_utils.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/logging/log_manager.hpp" diff --git a/src/duckdb/src/main/metrics_manager.cpp b/src/duckdb/src/main/profiler/metrics_manager.cpp similarity index 97% rename from src/duckdb/src/main/metrics_manager.cpp rename to src/duckdb/src/main/profiler/metrics_manager.cpp index 670a4c5bf..d4034b812 100644 --- a/src/duckdb/src/main/metrics_manager.cpp +++ b/src/duckdb/src/main/profiler/metrics_manager.cpp @@ -1,5 +1,5 @@ -#include "duckdb/main/metrics_manager.hpp" -#include "duckdb/main/metrics.hpp" +#include "duckdb/main/profiler/metrics_manager.hpp" +#include "duckdb/main/profiler/metrics.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/common/enums/optimizer_type.hpp" diff --git a/src/duckdb/src/main/profiling_utils.cpp b/src/duckdb/src/main/profiler/profiling_utils.cpp similarity index 94% rename from src/duckdb/src/main/profiling_utils.cpp rename to src/duckdb/src/main/profiler/profiling_utils.cpp index 39aeafa18..db7db2b1a 100644 --- a/src/duckdb/src/main/profiling_utils.cpp +++ b/src/duckdb/src/main/profiler/profiling_utils.cpp @@ -1,4 +1,4 @@ -#include "duckdb/main/profiling_utils.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" #include "duckdb/common/string_util.hpp" namespace duckdb { diff --git a/src/duckdb/src/main/query_profiler.cpp b/src/duckdb/src/main/query_profiler.cpp index 9a9cd5329..4ae991a35 100644 --- a/src/duckdb/src/main/query_profiler.cpp +++ b/src/duckdb/src/main/query_profiler.cpp @@ -6,14 +6,15 @@ #include "duckdb/common/optional_idx.hpp" #include "duckdb/common/printer.hpp" #include "duckdb/common/string_util.hpp" +#include "duckdb/common/tree_renderer.hpp" #include "duckdb/common/tree_renderer/text_tree_renderer.hpp" #include "duckdb/execution/operator/scan/physical_table_scan.hpp" #include "duckdb/execution/physical_operator.hpp" #include "duckdb/main/client_config.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/main/client_data.hpp" -#include "duckdb/main/profiling_utils.hpp" -#include "duckdb/main/gathered_metrics.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" +#include "duckdb/main/profiler/gathered_metrics.hpp" #include "duckdb/main/settings.hpp" #include "duckdb/storage/buffer/buffer_pool.hpp" #include "yyjson.hpp" @@ -80,59 +81,28 @@ bool QueryProfiler::IsEnabled() const { return is_explain_analyze || ClientConfig::GetConfig(context).enable_profiler; } -bool QueryProfiler::IsDetailedEnabled() const { - return !is_explain_analyze && ClientConfig::GetConfig(context).enable_detailed_profiling; +unique_ptr QueryProfiler::CreateProfiler(const string &name) const { + // formats are resolved through the renderer registry, which matches case-insensitively and throws on + // unrecognized formats - "no_output" has no renderer, for which CreateRenderer returns nullptr + auto renderer = TreeRenderer::CreateRenderer(name); + if (renderer) { + renderer->Configure(ClientConfig::GetConfig(context).profiling_renderer_settings); + } + return renderer; } -ProfilerPrintFormat QueryProfiler::GetPrintFormat(ExplainFormat format) const { - auto print_format = ClientConfig::GetConfig(context).profiler_print_format; - switch (format) { - case ExplainFormat::DEFAULT: - if (print_format != ProfilerPrintFormat::NO_OUTPUT) { - return print_format; - } - DUCKDB_EXPLICIT_FALLTHROUGH; - case ExplainFormat::TEXT: - return ProfilerPrintFormat::QUERY_TREE; - case ExplainFormat::JSON: - return ProfilerPrintFormat::JSON; - case ExplainFormat::HTML: - return ProfilerPrintFormat::HTML; - case ExplainFormat::GRAPHVIZ: - return ProfilerPrintFormat::GRAPHVIZ; - case ExplainFormat::MERMAID: - return ProfilerPrintFormat::MERMAID; - default: - throw NotImplementedException("No mapping from ExplainFormat::%s to ProfilerPrintFormat", - EnumUtil::ToString(format)); - } -} - -ExplainFormat QueryProfiler::GetExplainFormat(ProfilerPrintFormat format) const { - switch (format) { - case ProfilerPrintFormat::QUERY_TREE: - case ProfilerPrintFormat::QUERY_TREE_OPTIMIZER: - return ExplainFormat::TEXT; - case ProfilerPrintFormat::JSON: - return ExplainFormat::JSON; - case ProfilerPrintFormat::HTML: - return ExplainFormat::HTML; - case ProfilerPrintFormat::GRAPHVIZ: - return ExplainFormat::GRAPHVIZ; - case ProfilerPrintFormat::MERMAID: - return ExplainFormat::MERMAID; - case ProfilerPrintFormat::NO_OUTPUT: - throw InternalException("Should not attempt to get ExplainFormat for ProfilerPrintFormat::NO_OUTPUT"); - default: - throw NotImplementedException("No mapping from ProfilePrintFormat::%s to ExplainFormat", - EnumUtil::ToString(format)); +unique_ptr QueryProfiler::GetRenderer(const ProfilerPrintFormat &format) const { + if (format == ProfilerPrintFormat::Default()) { + // use the configured default profiler format; "no_output" still renders as a query tree when explicitly asked + // for output (e.g. EXPLAIN ANALYZE), so fall back to it here + auto name = ClientConfig::GetConfig(context).profiler_print_format; + return CreateProfiler(name == "no_output" ? "query_tree" : name); } + // resolve the explain format name (text/json/html/...) and create the matching renderer + return CreateProfiler(format.ToString()); } bool QueryProfiler::PrintOptimizerOutput() const { - if (GetPrintFormat() == ProfilerPrintFormat::QUERY_TREE_OPTIMIZER || IsDetailedEnabled()) { - return true; - } if (metrics) { return metrics->MetricIsTracked("optimizer.join_order"); } @@ -253,8 +223,8 @@ void QueryProfiler::EndQuery() { bool emit_output = false; // Print or output the query profiling after query termination. - // EXPLAIN ANALYZE output is not written by the profiler. - if (IsEnabled() && !is_explain_analyze && ClientConfig::GetConfig(context).emit_profiler_output) { + // EXPLAIN ANALYZE output is not written by the profiler, and the "no_output" format emits no output. + if (!is_explain_analyze && ClientConfig::GetConfig(context).profiler_print_format != "no_output") { emit_output = true; } @@ -327,39 +297,37 @@ MetricsTimer QueryProfiler::StartTimerInternal(const string &key) { return MetricsTimer(query_metrics, key, IsEnabled()); } -string QueryProfiler::ToString(ExplainFormat explain_format) const { - return ToString(GetPrintFormat(explain_format)); +string QueryProfiler::ToString(const ProfilerPrintFormat &format) const { + auto renderer = GetRenderer(format); + return RenderProfilerOutput(renderer.get()); } -string QueryProfiler::ToString(ProfilerPrintFormat format) const { - if (!IsEnabled()) { - return RenderDisabledMessage(format); - } - switch (format) { - case ProfilerPrintFormat::QUERY_TREE: - case ProfilerPrintFormat::QUERY_TREE_OPTIMIZER: - return QueryTreeToString(); - case ProfilerPrintFormat::JSON: - return ToJSON(); - case ProfilerPrintFormat::NO_OUTPUT: +string QueryProfiler::ToString(const string &profiler_format_name) const { + auto renderer = CreateProfiler(profiler_format_name); + return RenderProfilerOutput(renderer.get()); +} + +string QueryProfiler::RenderProfilerOutput(optional_ptr renderer) const { + if (!renderer) { + // "no_output" format: nothing is rendered, enabled or not return ""; - case ProfilerPrintFormat::HTML: - case ProfilerPrintFormat::GRAPHVIZ: - case ProfilerPrintFormat::MERMAID: { - lock_guard guard(lock); - // checking the tree to ensure the query is really empty - // the query string is empty when a logical plan is deserialized - if (query_metrics.query_sql.empty() || !root) { - return ""; - } - auto renderer = TreeRenderer::CreateRenderer(GetExplainFormat(format)); - stringstream str; - renderer->Render(*root, str); - return str.str(); } - default: - throw InternalException("Unknown ProfilerPrintFormat \"%s\"", EnumUtil::ToString(format)); + if (!IsEnabled()) { + return renderer->RenderProfilerDisabled(); } + return renderer->RenderProfiler(*this); +} + +string QueryProfiler::RenderProfilingNodeTree(TreeRenderer &renderer) const { + lock_guard guard(lock); + // checking the tree to ensure the query is really empty + // the query string is empty when a logical plan is deserialized + if (query_metrics.query_sql.empty() || !root) { + return ""; + } + stringstream str; + renderer.Render(*root, str); + return str.str(); } OperatorProfiler::OperatorProfiler(ClientContext &context) : context(context) { @@ -1053,47 +1021,6 @@ unique_ptr QueryProfiler::CreateTree(const PhysicalOperator &root return node; } -string QueryProfiler::RenderDisabledMessage(ProfilerPrintFormat format) const { - switch (format) { - case ProfilerPrintFormat::NO_OUTPUT: - return ""; - case ProfilerPrintFormat::QUERY_TREE: - case ProfilerPrintFormat::QUERY_TREE_OPTIMIZER: - return "Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling!"; - case ProfilerPrintFormat::HTML: - return R"( - - - Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling! - - )"; - case ProfilerPrintFormat::GRAPHVIZ: - return R"( - digraph G { - node [shape=box, style=rounded, fontname="Courier New", fontsize=10]; - node_0_0 [label="Query profiling is disabled. Use 'PRAGMA enable_profiling;' to enable profiling!"]; - } - )"; - case ProfilerPrintFormat::MERMAID: - return R"(flowchart TD - node_0_0["`**DISABLED** -Query profiling is disabled. -Use 'PRAGMA enable_profiling;' to enable profiling!`"] -)"; - case ProfilerPrintFormat::JSON: { - ConvertedJSONHolder json_holder; - json_holder.doc = yyjson_mut_doc_new(nullptr); - auto result_obj = yyjson_mut_obj(json_holder.doc); - yyjson_mut_doc_set_root(json_holder.doc, result_obj); - - yyjson_mut_obj_add_str(json_holder.doc, result_obj, "result", "disabled"); - return StringifyAndFree(json_holder, result_obj); - } - default: - throw InternalException("Unknown ProfilerPrintFormat \"%s\"", EnumUtil::ToString(format)); - } -} - void QueryProfiler::Initialize(const PhysicalOperator &root_op) { lock_guard guard(lock); if (!IsEnabled() || !running) { @@ -1114,11 +1041,7 @@ void QueryProfiler::Initialize(const PhysicalOperator &root_op) { void QueryProfiler::Render(const ProfilingNode &node, std::ostream &ss) const { TextTreeRenderer renderer; - if (IsDetailedEnabled()) { - renderer.EnableDetailed(); - } else { - renderer.EnableStandard(); - } + renderer.Configure(ClientConfig::GetConfig(context).profiling_renderer_settings); renderer.Render(node, ss); } diff --git a/src/duckdb/src/main/relation.cpp b/src/duckdb/src/main/relation.cpp index 8f59982ea..45f4ee9dc 100644 --- a/src/duckdb/src/main/relation.cpp +++ b/src/duckdb/src/main/relation.cpp @@ -366,7 +366,7 @@ unique_ptr Relation::Query(const Identifier &name, const string &sq return Query(sql); } -unique_ptr Relation::Explain(ExplainType type, ExplainFormat format) { +unique_ptr Relation::Explain(ExplainType type, const ProfilerPrintFormat &format) { auto explain = make_shared_ptr(shared_from_this(), type, format); return explain->Execute(); } diff --git a/src/duckdb/src/main/relation/explain_relation.cpp b/src/duckdb/src/main/relation/explain_relation.cpp index 9f2976c9d..5bc461e69 100644 --- a/src/duckdb/src/main/relation/explain_relation.cpp +++ b/src/duckdb/src/main/relation/explain_relation.cpp @@ -7,7 +7,7 @@ namespace duckdb { -ExplainRelation::ExplainRelation(shared_ptr child_p, ExplainType type, ExplainFormat format) +ExplainRelation::ExplainRelation(shared_ptr child_p, ExplainType type, const ProfilerPrintFormat &format) : Relation(child_p->context, RelationType::EXPLAIN_RELATION), child(std::move(child_p)), type(type), format(format) { TryBindRelation(columns); diff --git a/src/duckdb/src/main/settings/custom_settings.cpp b/src/duckdb/src/main/settings/custom_settings.cpp index a4da981b8..8b3db9d8a 100644 --- a/src/duckdb/src/main/settings/custom_settings.cpp +++ b/src/duckdb/src/main/settings/custom_settings.cpp @@ -11,6 +11,7 @@ #include "duckdb/main/settings.hpp" +#include "duckdb/common/algorithm.hpp" #include "duckdb/common/constants.hpp" #include "duckdb/common/enums/access_mode.hpp" #include "duckdb/common/enum_util.hpp" @@ -24,6 +25,7 @@ #include "duckdb/main/config.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" +#include "duckdb/common/tree_renderer.hpp" #include "duckdb/main/extension_helper.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/main/secret/secret_manager.hpp" @@ -862,8 +864,11 @@ void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input auto parameter = StringUtil::Lower(input.ToString()); auto &config = ClientConfig::GetConfig(context); + + // Validate the format name (throws on an unrecognized format). + QueryProfiler::Get(context).CreateProfiler(parameter); + config.enable_profiler = true; - config.emit_profiler_output = true; if (parameter != "no_output" && !config.profiler_save_location.empty()) { auto &file_system = FileSystem::GetFileSystem(context); @@ -876,31 +881,13 @@ void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input } } - if (parameter == "json") { - config.profiler_print_format = ProfilerPrintFormat::JSON; - } else if (parameter == "query_tree") { - config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE; - } else if (parameter == "query_tree_optimizer") { - config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE_OPTIMIZER; - } else if (parameter == "no_output") { - config.profiler_print_format = ProfilerPrintFormat::NO_OUTPUT; - config.emit_profiler_output = false; - } else if (parameter == "html") { - config.profiler_print_format = ProfilerPrintFormat::HTML; - } else if (parameter == "graphviz") { - config.profiler_print_format = ProfilerPrintFormat::GRAPHVIZ; - } else { - throw ParserException("Unrecognized print format %s, supported formats: [json, query_tree, " - "query_tree_optimizer, no_output, html, graphviz]", - parameter); - } + config.profiler_print_format = parameter; } void EnableProfilingSetting::ResetLocal(ClientContext &context) { auto &config = ClientConfig::GetConfig(context); config.profiler_print_format = ClientConfig().profiler_print_format; config.enable_profiler = ClientConfig().enable_profiler; - config.emit_profiler_output = ClientConfig().emit_profiler_output; } Value EnableProfilingSetting::GetSetting(const ClientContext &context) { @@ -908,22 +895,7 @@ Value EnableProfilingSetting::GetSetting(const ClientContext &context) { if (!config.enable_profiler) { return Value(); } - switch (config.profiler_print_format) { - case ProfilerPrintFormat::JSON: - return Value("json"); - case ProfilerPrintFormat::QUERY_TREE: - return Value("query_tree"); - case ProfilerPrintFormat::QUERY_TREE_OPTIMIZER: - return Value("query_tree_optimizer"); - case ProfilerPrintFormat::NO_OUTPUT: - return Value("no_output"); - case ProfilerPrintFormat::HTML: - return Value("html"); - case ProfilerPrintFormat::GRAPHVIZ: - return Value("graphviz"); - default: - throw InternalException("Unsupported profiler print format"); - } + return Value(config.profiler_print_format); } //===----------------------------------------------------------------------===// @@ -1226,22 +1198,22 @@ void PerfectHtThresholdSetting::OnSet(SettingCallbackInfo &info, Value &input) { //===----------------------------------------------------------------------===// // Profile Output //===----------------------------------------------------------------------===// -void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) { +void ProfilingOutputSetting::SetLocal(ClientContext &context, const Value &input) { auto &config = ClientConfig::GetConfig(context); auto parameter = input.ToString(); - if (!parameter.empty() && config.profiler_print_format != ProfilerPrintFormat::NO_OUTPUT) { + if (!parameter.empty() && config.profiler_print_format != "no_output") { auto &file_system = FileSystem::GetFileSystem(context); const auto file_type = file_system.ExtractExtension(parameter); if (file_type != "txt") { try { - EnumUtil::FromString(file_type); + QueryProfiler::Get(context).CreateProfiler(file_type); } catch (std::exception &e) { throw ParserException("Invalid output file type: %s", file_type); } } - const auto printer_format = StringUtil::Lower(EnumUtil::ToString(config.profiler_print_format)); + const auto printer_format = config.profiler_print_format; if (file_type != printer_format && file_type != "txt") { throw ParserException("Profiler file type (%s) must either have the same file extension as the profiling " "output type (%s), or be a '.txt' file. Set \"enable_profiling = \'%s\'\" first.", @@ -1252,28 +1224,70 @@ void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) config.profiler_save_location = parameter; } -void ProfileOutputSetting::ResetLocal(ClientContext &context) { +void ProfilingOutputSetting::ResetLocal(ClientContext &context) { ClientConfig::GetConfig(context).profiler_save_location = ClientConfig().profiler_save_location; } -Value ProfileOutputSetting::GetSetting(const ClientContext &context) { +Value ProfilingOutputSetting::GetSetting(const ClientContext &context) { auto &config = ClientConfig::GetConfig(context); return Value(config.profiler_save_location); } +//===----------------------------------------------------------------------===// +// Profiler Renderer Settings +//===----------------------------------------------------------------------===// +void ProfilingRendererSettingsSetting::SetLocal(ClientContext &context, const Value &input) { + auto &config = ClientConfig::GetConfig(context); + if (input.IsNull() || input.type().id() != LogicalTypeId::MAP) { + throw InvalidInputException("Invalid profiling_renderer_settings type \"%s\", expected a map of settings " + "(e.g. {'maximum_render_width': 300})", + input.type().ToString()); + } + unordered_map new_settings; + for (auto &entry : MapValue::GetChildren(input)) { + auto &key_value = StructValue::GetChildren(entry); + new_settings[StringUtil::Lower(key_value[0].ToString())] = key_value[1]; + } + // eagerly configure the renderer of the current profiler format to validate the setting values + auto renderer = QueryProfiler::Get(context).GetRenderer(); + if (renderer) { + renderer->Configure(new_settings); + } + config.profiling_renderer_settings = std::move(new_settings); +} + +void ProfilingRendererSettingsSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).profiling_renderer_settings.clear(); +} + +Value ProfilingRendererSettingsSetting::GetSetting(const ClientContext &context) { + auto &config = ClientConfig::GetConfig(context); + // sort the settings by name so that the rendered value is deterministic + vector setting_names; + for (auto &entry : config.profiling_renderer_settings) { + setting_names.push_back(entry.first); + } + std::sort(setting_names.begin(), setting_names.end()); + vector keys; + vector values; + for (auto &name : setting_names) { + keys.emplace_back(name); + values.push_back(config.profiling_renderer_settings.at(name).DefaultCastAs(LogicalType::VARCHAR)); + } + return Value::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR, std::move(keys), std::move(values)); +} + //===----------------------------------------------------------------------===// // Profiling Mode //===----------------------------------------------------------------------===// void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = StringUtil::Lower(input.ToString()); auto &config = ClientConfig::GetConfig(context); - if (parameter == "standard") { - config.enable_profiler = true; - config.enable_detailed_profiling = false; - } else if (parameter == "detailed") { - config.enable_profiler = true; - config.enable_detailed_profiling = true; - } else if (parameter == "all") { + if (parameter == "standard" || parameter == "detailed" || parameter == "all") { + // the profiling_mode setting is deprecated - detailed profiling information is always gathered, and all + // modes behave the same + DUCKDB_LOG_WARNING(context, "the profiling_mode setting is deprecated: detailed profiling information is " + "always collected - use \"PRAGMA enable_profiling\" to enable profiling instead"); config.enable_profiler = true; } else { throw ParserException("Unrecognized profiling mode \"%s\", supported formats: [standard, detailed, all]", @@ -1284,8 +1298,6 @@ void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) void ProfilingModeSetting::ResetLocal(ClientContext &context) { auto &config = ClientConfig::GetConfig(context); config.enable_profiler = ClientConfig().enable_profiler; - config.enable_detailed_profiling = ClientConfig().enable_detailed_profiling; - config.emit_profiler_output = ClientConfig().emit_profiler_output; } Value ProfilingModeSetting::GetSetting(const ClientContext &context) { @@ -1293,7 +1305,7 @@ Value ProfilingModeSetting::GetSetting(const ClientContext &context) { if (!config.enable_profiler) { return Value(); } - return Value(config.enable_detailed_profiling ? "detailed" : "standard"); + return Value("standard"); } //===----------------------------------------------------------------------===// diff --git a/src/duckdb/src/optimizer/unnest_rewriter.cpp b/src/duckdb/src/optimizer/unnest_rewriter.cpp index 22451dd21..c375c96de 100644 --- a/src/duckdb/src/optimizer/unnest_rewriter.cpp +++ b/src/duckdb/src/optimizer/unnest_rewriter.cpp @@ -8,15 +8,59 @@ #include "duckdb/planner/expression/bound_columnref_expression.hpp" #include "duckdb/planner/expression/bound_unnest_expression.hpp" #include "duckdb/planner/logical_operator.hpp" +#include "duckdb/planner/operator/logical_aggregate.hpp" #include "duckdb/planner/operator/logical_comparison_join.hpp" +#include "duckdb/planner/operator/logical_cteref.hpp" #include "duckdb/planner/operator/logical_delim_get.hpp" #include "duckdb/planner/operator/logical_get.hpp" +#include "duckdb/planner/operator/logical_materialized_cte.hpp" #include "duckdb/planner/operator/logical_projection.hpp" #include "duckdb/planner/operator/logical_unnest.hpp" #include "duckdb/planner/expression_binder.hpp" +#include + namespace duckdb { +static bool IsSupportedUnnestTop(LogicalOperatorType type) { + return type == LogicalOperatorType::LOGICAL_PROJECTION || type == LogicalOperatorType::LOGICAL_WINDOW || + type == LogicalOperatorType::LOGICAL_FILTER || type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY || + type == LogicalOperatorType::LOGICAL_UNNEST; +} + +static optional_idx FindBindingIndex(const vector &bindings, const ColumnBinding &binding) { + auto entry = std::find(bindings.begin(), bindings.end(), binding); + if (entry == bindings.end()) { + return optional_idx(); + } + return NumericCast(entry - bindings.begin()); +} + +static idx_t CountCTERefs(LogicalOperator &op, TableIndex cte_index) { + idx_t result = 0; + if (op.type == LogicalOperatorType::LOGICAL_CTE_REF && op.Cast().cte_index == cte_index) { + result++; + } + for (auto &child : op.children) { + result += CountCTERefs(*child, cte_index); + } + return result; +} + +static bool IsCTERef(LogicalOperator &op, TableIndex cte_index) { + return op.type == LogicalOperatorType::LOGICAL_CTE_REF && op.Cast().cte_index == cte_index; +} + +static optional_idx FindCTERefSide(LogicalComparisonJoin &join, TableIndex cte_index) { + if (IsCTERef(*join.children[0], cte_index)) { + return optional_idx(0); + } + if (IsCTERef(*join.children[1], cte_index)) { + return optional_idx(1); + } + return optional_idx(); +} + void UnnestRewriterPlanUpdater::VisitOperator(LogicalOperator &op) { VisitOperatorChildren(op); VisitOperatorExpressions(op); @@ -58,6 +102,7 @@ unique_ptr UnnestRewriter::Optimize(unique_ptr } } + RewriteCTECandidates(op, op, updater); return op; } @@ -181,13 +226,397 @@ void UnnestRewriter::FindCandidates(unique_ptr &root, unique_pt } } +static bool ConvertCTETableInOutUnnest(unique_ptr &root, unique_ptr &op, + TableIndex input_cte_index, bool require_input_cte_ref = true) { + if (op->type != LogicalOperatorType::LOGICAL_GET) { + return false; + } + auto &get = op->Cast(); + if (!ExpressionBinder::IsUnnestFunction(get.function.name) || get.ordinality_idx.IsValid()) { + return false; + } + if (op->children.size() != 1 || op->children[0]->type != LogicalOperatorType::LOGICAL_PROJECTION) { + return false; + } + auto &proj = op->children[0]->Cast(); + if (proj.children.size() != 1) { + return false; + } + if (require_input_cte_ref && !IsCTERef(*proj.children[0], input_cte_index)) { + return false; + } + + auto unnest_get_column = op->GetColumnBindings(); + auto unnest_get_index = op->GetTableIndex()[0]; + op->ResolveOperatorTypes(); + for (idx_t i = 0; i < unnest_get_column.size(); i++) { + auto &col_bind = unnest_get_column[i]; + if (col_bind.table_index != unnest_get_index) { + continue; + } + auto &expr = proj.GetExpression(col_bind.column_index); + if (expr.GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF) { + return false; + } + } + + auto unnest_get = std::move(op); + ColumnBindingReplacer replacer; + auto cte_ref = std::move(proj.children[0]); + auto unnest = make_uniq(unnest_get_index); + unnest->children.push_back(std::move(cte_ref)); + op = std::move(unnest_get->children[0]); + for (idx_t i = 0; i < unnest_get_column.size(); i++) { + auto &col_bind = unnest_get_column[i]; + D_ASSERT(col_bind.table_index == unnest_get_index || col_bind.table_index == proj.table_index); + if (col_bind.table_index != unnest_get_index) { + continue; + } + auto &bind_col = proj.expressions[col_bind.column_index]->Cast(); + auto unnest_expr = make_uniq(unnest_get->types[i]); + unnest_expr->ChildMutable() = proj.expressions[col_bind.column_index]->Copy(); + bind_col.BindingMutable() = ColumnBinding(unnest_get_index, bind_col.Binding().column_index); + auto unnest_proj_idx = ColumnBinding::PushExpression(unnest->expressions, std::move(unnest_expr)); + ColumnBinding new_column_ref(bind_col.Binding().table_index, unnest_proj_idx); + auto unnest_ref = make_uniq(bind_col.GetAlias(), unnest_get->types[i], new_column_ref, + bind_col.Depth()); + proj.expressions[col_bind.column_index] = std::move(unnest_ref); + proj.types[col_bind.column_index] = unnest_get->types[i]; + replacer.replacement_bindings.push_back( + ReplacementBinding(col_bind, ColumnBinding(proj.table_index, col_bind.column_index), unnest_get->types[i])); + } + proj.children[0] = std::move(unnest); + replacer.stop_operator = proj; + replacer.VisitOperator(*root); + return true; +} + +static bool GetInlineDedupColumns(LogicalMaterializedCTE &domain_cte, LogicalOperator &dedup_op, + vector &dedup_columns) { + // An earlier CTE inlining pass can remove the explicit dedup CTE. Trace the bindings emitted below UNNEST back + // through projections and the aggregate groups to recover the original delimiter columns from the domain producer. + domain_cte.children[0]->ResolveOperatorTypes(); + auto source_bindings = domain_cte.children[0]->GetColumnBindings(); + vector traced_bindings = dedup_op.GetColumnBindings(); + + reference current_op(dedup_op); + while (current_op.get().type == LogicalOperatorType::LOGICAL_PROJECTION) { + auto &projection = current_op.get().Cast(); + if (projection.children.size() != 1) { + return false; + } + auto current_bindings = projection.GetColumnBindings(); + for (auto &binding : traced_bindings) { + auto binding_idx = FindBindingIndex(current_bindings, binding); + if (!binding_idx.IsValid()) { + continue; + } + if (binding_idx.GetIndex() >= projection.expressions.size()) { + return false; + } + auto &expr = projection.GetExpression(ProjectionIndex(binding_idx.GetIndex())); + if (expr.GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF) { + return false; + } + auto &colref = expr.Cast(); + if (colref.Depth() != 0) { + return false; + } + binding = colref.Binding(); + } + current_op = *projection.children[0]; + } + + if (current_op.get().type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY) { + return false; + } + auto &aggregate = current_op.get().Cast(); + if (aggregate.children.size() != 1 || !IsCTERef(*aggregate.children[0], domain_cte.table_index)) { + return false; + } + auto aggregate_bindings = aggregate.GetColumnBindings(); + auto aggregate_child_bindings = aggregate.children[0]->GetColumnBindings(); + for (auto &binding : traced_bindings) { + auto aggregate_idx = FindBindingIndex(aggregate_bindings, binding); + optional_idx source_idx; + if (!aggregate_idx.IsValid()) { + source_idx = FindBindingIndex(aggregate_child_bindings, binding); + } else { + if (aggregate_idx.GetIndex() >= aggregate.groups.size()) { + return false; + } + auto &group = aggregate.groups[aggregate_idx.GetIndex()]; + if (group->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF) { + return false; + } + auto &colref = group->Cast(); + if (colref.Depth() != 0) { + return false; + } + source_idx = FindBindingIndex(aggregate_child_bindings, colref.Binding()); + } + if (!source_idx.IsValid() || source_idx.GetIndex() >= source_bindings.size()) { + return false; + } + dedup_columns.push_back(source_bindings[source_idx.GetIndex()]); + } + return !dedup_columns.empty(); +} + +bool UnnestRewriter::RewriteCTECandidates(unique_ptr &root, unique_ptr &op, + UnnestRewriterPlanUpdater &updater) { + bool changed = false; + for (auto &child : op->children) { + changed = RewriteCTECandidates(root, child, updater) || changed; + } + return RewriteCTECandidate(root, op, updater) || changed; +} + +bool UnnestRewriter::RewriteInlineCTEDedupCandidate(unique_ptr &root, + unique_ptr &candidate, + UnnestRewriterPlanUpdater &updater) { + auto &domain_cte = candidate->Cast(); + if (CountCTERefs(*candidate, domain_cte.table_index) != 2) { + return false; + } + + idx_t topmost_depth = 0; + auto topmost_ptr = &domain_cte.children[1]; + while (topmost_ptr->get()->type == LogicalOperatorType::LOGICAL_PROJECTION && + topmost_ptr->get()->children.size() == 1 && + topmost_ptr->get()->children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + topmost_ptr = &topmost_ptr->get()->children[0]; + topmost_depth++; + } + auto &topmost_op = *topmost_ptr->get(); + if (!IsSupportedUnnestTop(topmost_op.type) || topmost_op.children.size() != 1 || + topmost_op.children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + return false; + } + + auto &join = topmost_op.children[0]->Cast(); + if (join.join_type != JoinType::INNER || join.conditions.size() != 1 || join.children.size() != 2) { + return false; + } + + auto domain_side = FindCTERefSide(join, domain_cte.table_index); + if (!domain_side.IsValid()) { + return false; + } + idx_t other_side = 1 - domain_side.GetIndex(); + auto domain_ref_bindings = join.children[domain_side.GetIndex()]->GetColumnBindings(); + if (join.children[other_side]->type == LogicalOperatorType::LOGICAL_GET && + !ConvertCTETableInOutUnnest(root, join.children[other_side], domain_cte.table_index, false)) { + return false; + } + + vector>> path_to_unnest; + reference> current_op = join.children[other_side]; + while (current_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + if (current_op.get()->children.size() != 1) { + return false; + } + path_to_unnest.push_back(current_op); + current_op = current_op.get()->children[0]; + } + if (current_op.get()->type != LogicalOperatorType::LOGICAL_UNNEST) { + return false; + } + auto &unnest = current_op.get()->Cast(); + if (unnest.children.size() != 1) { + return false; + } + + vector candidate_delim_columns; + if (!GetInlineDedupColumns(domain_cte, *unnest.children[0], candidate_delim_columns)) { + return false; + } + auto dedup_bindings = unnest.children[0]->GetColumnBindings(); + if (dedup_bindings.size() != candidate_delim_columns.size()) { + return false; + } + + delim_columns = std::move(candidate_delim_columns); + GetLHSExpressions(*domain_cte.children[0]); + if (domain_ref_bindings.size() != lhs_bindings.size()) { + delim_columns.clear(); + lhs_bindings.clear(); + return false; + } + + // After replacing the CTE refs by the shared domain producer, expressions in the join subtree must read + // directly from the producer bindings. The dedup bindings are retargeted to their original delimiter columns. + ColumnBindingReplacer domain_ref_replacer; + for (idx_t binding_idx = 0; binding_idx < lhs_bindings.size(); binding_idx++) { + domain_ref_replacer.replacement_bindings.emplace_back( + domain_ref_bindings[binding_idx], lhs_bindings[binding_idx].binding, lhs_bindings[binding_idx].type); + } + for (idx_t binding_idx = 0; binding_idx < dedup_bindings.size(); binding_idx++) { + domain_ref_replacer.replacement_bindings.emplace_back(dedup_bindings[binding_idx], delim_columns[binding_idx]); + } + LogicalOperatorVisitor::EnumerateExpressions( + topmost_op, [&](unique_ptr *expr) { domain_ref_replacer.VisitExpression(expr); }); + overwritten_tbl_idx = dedup_bindings[0].table_index; + distinct_unnest_count = dedup_bindings.size(); + + unnest.children[0] = std::move(domain_cte.children[0]); + if (path_to_unnest.empty()) { + updater.replace_bindings.clear(); + for (idx_t binding_idx = 0; binding_idx < dedup_bindings.size(); binding_idx++) { + updater.replace_bindings.emplace_back(dedup_bindings[binding_idx], delim_columns[binding_idx]); + } + for (auto &unnest_expr : unnest.expressions) { + updater.VisitExpression(&unnest_expr); + } + updater.replace_bindings.clear(); + topmost_op.children[0] = std::move(current_op.get()); + candidate = std::move(domain_cte.children[1]); + delim_columns.clear(); + lhs_bindings.clear(); + return true; + } + topmost_op.children[0] = std::move(path_to_unnest.front().get()); + + candidate = std::move(domain_cte.children[1]); + reference> rewritten_topmost_ptr = candidate; + for (idx_t depth = 0; depth < topmost_depth; depth++) { + rewritten_topmost_ptr = rewritten_topmost_ptr.get()->children[0]; + } + + updater.overwritten_tbl_idx = overwritten_tbl_idx; + UpdateBoundUnnestBindings(updater, rewritten_topmost_ptr.get()); + UpdateRHSBindings(root, rewritten_topmost_ptr.get(), updater); + + delim_columns.clear(); + lhs_bindings.clear(); + return true; +} + +bool UnnestRewriter::RewriteCTECandidate(unique_ptr &root, unique_ptr &candidate, + UnnestRewriterPlanUpdater &updater) { + if (candidate->type != LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) { + return false; + } + auto &domain_cte = candidate->Cast(); + if (domain_cte.materialize != CTEMaterialize::CTE_MATERIALIZE_DEFAULT || domain_cte.children.size() != 2) { + return false; + } + if (RewriteInlineCTEDedupCandidate(root, candidate, updater)) { + return true; + } + if (domain_cte.children[1]->type != LogicalOperatorType::LOGICAL_PROJECTION || + domain_cte.children[1]->children.size() != 1 || + domain_cte.children[1]->children[0]->type != LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) { + return false; + } + + auto &outer_projection = domain_cte.children[1]->Cast(); + auto &dedup_cte = outer_projection.children[0]->Cast(); + if (dedup_cte.materialize != CTEMaterialize::CTE_MATERIALIZE_DEFAULT || dedup_cte.children.size() != 2) { + return false; + } + if (dedup_cte.children[0]->type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY) { + return false; + } + auto &dedup = dedup_cte.children[0]->Cast(); + if (dedup.children.size() != 1 || !IsCTERef(*dedup.children[0], domain_cte.table_index)) { + return false; + } + + domain_cte.children[0]->ResolveOperatorTypes(); + auto source_bindings = domain_cte.children[0]->GetColumnBindings(); + auto dedup_child_bindings = dedup.children[0]->GetColumnBindings(); + vector candidate_delim_columns; + for (auto &group : dedup.groups) { + if (group->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF) { + return false; + } + auto &colref = group->Cast(); + if (colref.Depth() != 0) { + return false; + } + auto source_idx = FindBindingIndex(dedup_child_bindings, colref.Binding()); + if (!source_idx.IsValid() || source_idx.GetIndex() >= source_bindings.size()) { + return false; + } + candidate_delim_columns.push_back(source_bindings[source_idx.GetIndex()]); + } + if (candidate_delim_columns.empty() || candidate_delim_columns.size() != dedup_cte.column_count) { + return false; + } + + if (CountCTERefs(*candidate, domain_cte.table_index) != 2 || CountCTERefs(*candidate, dedup_cte.table_index) != 1) { + return false; + } + + auto &topmost_op = *dedup_cte.children[1]; + if (!IsSupportedUnnestTop(topmost_op.type) || topmost_op.children.size() != 1 || + topmost_op.children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + return false; + } + auto &join = topmost_op.children[0]->Cast(); + if (join.join_type != JoinType::INNER || join.conditions.size() != 1 || join.children.size() != 2) { + return false; + } + + auto domain_side = FindCTERefSide(join, domain_cte.table_index); + if (!domain_side.IsValid()) { + return false; + } + idx_t other_side = 1 - domain_side.GetIndex(); + + if (join.children[other_side]->type == LogicalOperatorType::LOGICAL_GET && + !ConvertCTETableInOutUnnest(root, join.children[other_side], dedup_cte.table_index)) { + return false; + } + + vector>> path_to_unnest; + reference> current_op = join.children[other_side]; + while (current_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + if (current_op.get()->children.size() != 1) { + return false; + } + path_to_unnest.push_back(current_op); + current_op = current_op.get()->children[0]; + } + if (path_to_unnest.empty() || current_op.get()->type != LogicalOperatorType::LOGICAL_UNNEST) { + return false; + } + auto &unnest = current_op.get()->Cast(); + if (unnest.children.size() != 1 || !IsCTERef(*unnest.children[0], dedup_cte.table_index)) { + return false; + } + auto &dedup_ref = unnest.children[0]->Cast(); + if (dedup_ref.chunk_types.size() != candidate_delim_columns.size()) { + return false; + } + + delim_columns = std::move(candidate_delim_columns); + GetLHSExpressions(*domain_cte.children[0]); + overwritten_tbl_idx = dedup_ref.table_index; + distinct_unnest_count = dedup_ref.chunk_types.size(); + + unnest.children[0] = std::move(domain_cte.children[0]); + topmost_op.children[0] = std::move(path_to_unnest.front().get()); + + updater.overwritten_tbl_idx = overwritten_tbl_idx; + UpdateBoundUnnestBindings(updater, dedup_cte.children[1]); + UpdateRHSBindings(root, dedup_cte.children[1], updater); + + auto replacement = std::move(domain_cte.children[1]); + auto &replacement_projection = replacement->Cast(); + auto &replacement_dedup_cte = replacement_projection.children[0]->Cast(); + replacement_projection.children[0] = std::move(replacement_dedup_cte.children[1]); + candidate = std::move(replacement); + + delim_columns.clear(); + lhs_bindings.clear(); + return true; +} + bool UnnestRewriter::RewriteCandidate(unique_ptr &candidate) { auto &topmost_op = *candidate; - if (topmost_op.type != LogicalOperatorType::LOGICAL_PROJECTION && - topmost_op.type != LogicalOperatorType::LOGICAL_WINDOW && - topmost_op.type != LogicalOperatorType::LOGICAL_FILTER && - topmost_op.type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY && - topmost_op.type != LogicalOperatorType::LOGICAL_UNNEST) { + if (!IsSupportedUnnestTop(topmost_op.type)) { return false; } @@ -208,17 +637,17 @@ bool UnnestRewriter::RewriteCandidate(unique_ptr &candidate) { // find the LOGICAL_UNNEST // and get the path down to the LOGICAL_UNNEST - vector *> path_to_unnest; - auto curr_op = &delim_join.children[other_idx]; - while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + vector>> path_to_unnest; + reference> curr_op = delim_join.children[other_idx]; + while (curr_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { path_to_unnest.push_back(curr_op); - curr_op = &curr_op->get()->children[0]; + curr_op = curr_op.get()->children[0]; } // store the table index of the child of the LOGICAL_UNNEST // then update the plan by making the lhs_proj the child of the LOGICAL_UNNEST - D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); - auto &unnest = curr_op->get()->Cast(); + D_ASSERT(curr_op.get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = curr_op.get()->Cast(); D_ASSERT(unnest.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET); overwritten_tbl_idx = unnest.children[0]->Cast().table_index; @@ -229,7 +658,7 @@ bool UnnestRewriter::RewriteCandidate(unique_ptr &candidate) { unnest.children[0] = std::move(lhs_op); // replace the LOGICAL_DELIM_JOIN with its RHS child operator - topmost_op.children[0] = std::move(*path_to_unnest.front()); + topmost_op.children[0] = std::move(path_to_unnest.front().get()); return true; } @@ -238,29 +667,50 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr &plan, unique auto &topmost_op = *candidate; idx_t shift = lhs_bindings.size(); - vector *> path_to_unnest; - auto curr_op = &topmost_op.children[0]; - while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + vector>> path_to_unnest; + reference> curr_op = topmost_op.children[0]; + while (curr_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { path_to_unnest.push_back(curr_op); - D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION); - auto &proj = curr_op->get()->Cast(); - - // pop the unnest columns and the delim index + D_ASSERT(curr_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &proj = curr_op.get()->Cast(); D_ASSERT(proj.expressions.size() > distinct_unnest_count); - for (idx_t i = 0; i < distinct_unnest_count; i++) { - proj.expressions.pop_back(); + auto tbl_idx = proj.table_index; + auto payload_count = proj.expressions.size() - distinct_unnest_count; + + // The trailing columns are duplicate-eliminated delimiter columns. References to those slots should + // point at the prepended LHS columns after the rewrite, not at shifted payload columns. + for (idx_t i = payload_count; i < proj.expressions.size(); i++) { + auto &expr = proj.expressions[i]; + if (expr->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF) { + continue; + } + auto &colref = expr->Cast(); + auto removed_binding = colref.Binding(); + if (removed_binding.table_index == overwritten_tbl_idx && + removed_binding.column_index.GetIndex() < delim_columns.size()) { + // CTE-based rewrites can still reference the deduplicated input here; translate it back to the + // corresponding domain producer column before finding the new LHS projection slot. + removed_binding = delim_columns[removed_binding.column_index.GetIndex()]; + } + for (idx_t lhs_idx = 0; lhs_idx < lhs_bindings.size(); lhs_idx++) { + if (removed_binding == lhs_bindings[lhs_idx].binding) { + ColumnBinding source_binding(tbl_idx, ProjectionIndex(i)); + ColumnBinding target_binding(tbl_idx, ProjectionIndex(lhs_idx)); + updater.replace_bindings.emplace_back(source_binding, target_binding); + break; + } + } } + proj.expressions.resize(payload_count); // store all shifted current bindings - auto tbl_idx = proj.table_index; for (idx_t i = 0; i < proj.expressions.size(); i++) { ColumnBinding source_binding(tbl_idx, ProjectionIndex(i)); ColumnBinding target_binding(tbl_idx, ProjectionIndex(i + shift)); - ReplaceBinding replace_binding(source_binding, target_binding); - updater.replace_bindings.push_back(replace_binding); + updater.replace_bindings.emplace_back(source_binding, target_binding); } - curr_op = &curr_op->get()->children[0]; + curr_op = curr_op.get()->children[0]; } // update all bindings by shifting them @@ -277,8 +727,8 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr &plan, unique } // temporarily remove the BOUND_UNNESTs and the child of the LOGICAL_UNNEST from the plan - D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); - auto &unnest = curr_op->get()->Cast(); + D_ASSERT(curr_op.get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = curr_op.get()->Cast(); vector> temp_bound_unnests; for (auto &temp_bound_unnest : unnest.expressions) { temp_bound_unnests.push_back(std::move(temp_bound_unnest)); @@ -298,15 +748,11 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr &plan, unique // add the LHS expressions to each LOGICAL_PROJECTION for (idx_t i = path_to_unnest.size(); i > 0; i--) { - D_ASSERT(path_to_unnest[i - 1]->get()->type == LogicalOperatorType::LOGICAL_PROJECTION); - auto &proj = path_to_unnest[i - 1]->get()->Cast(); + D_ASSERT(path_to_unnest[i - 1].get()->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &proj = path_to_unnest[i - 1].get()->Cast(); // temporarily store the existing expressions - vector> existing_expressions; - for (idx_t expr_idx = 0; expr_idx < proj.expressions.size(); expr_idx++) { - existing_expressions.push_back(std::move(proj.expressions[expr_idx])); - } - + auto existing_expressions = std::move(proj.expressions); proj.expressions.clear(); // add the new expressions @@ -321,9 +767,11 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr &plan, unique } // add the existing expressions again - for (idx_t expr_idx = 0; expr_idx < existing_expressions.size(); expr_idx++) { - proj.expressions.push_back(std::move(existing_expressions[expr_idx])); + for (auto &expr : existing_expressions) { + proj.expressions.push_back(std::move(expr)); } + + proj.ResolveOperatorTypes(); } } @@ -332,14 +780,14 @@ void UnnestRewriter::UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &update auto &topmost_op = *candidate; // traverse LOGICAL_PROJECTION(s) - auto curr_op = &topmost_op.children[0]; - while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { - curr_op = &curr_op->get()->children[0]; + reference> curr_op = topmost_op.children[0]; + while (curr_op.get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + curr_op = curr_op.get()->children[0]; } // found the LOGICAL_UNNEST - D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); - auto &unnest = curr_op->get()->Cast(); + D_ASSERT(curr_op.get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = curr_op.get()->Cast(); D_ASSERT(unnest.children.size() == 1); auto unnest_cols = unnest.children[0]->GetColumnBindings(); diff --git a/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp b/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp index c3be3b8c1..e19b85832 100644 --- a/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp +++ b/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp @@ -137,7 +137,6 @@ void PEGTransformerFactory::RegisterCreateTable() { // create_table.gram REGISTER_TRANSFORM(TransformColLabelOrString); REGISTER_TRANSFORM(TransformIdentifier); - REGISTER_TRANSFORM(TransformCubeOrRollup); } void PEGTransformerFactory::RegisterExpression() { @@ -339,138 +338,15 @@ void PEGTransformerFactory::RegisterPivot() { } void PEGTransformerFactory::RegisterSelect() { - // select.gram - REGISTER_TRANSFORM(TransformSelectStatement); - REGISTER_TRANSFORM(TransformSelectStatementInternal); - REGISTER_TRANSFORM(TransformSelectSetOpChain); - REGISTER_TRANSFORM(TransformIntersectChain); - REGISTER_TRANSFORM(TransformSelectAtom); - REGISTER_TRANSFORM(TransformSetopClause); - REGISTER_TRANSFORM(TransformSetIntersectClause); - REGISTER_TRANSFORM(TransformSetopType); - REGISTER_TRANSFORM(TransformDistinctOrAll); - REGISTER_TRANSFORM(TransformSelectParens); - REGISTER_TRANSFORM(TransformSelectStatementType); - REGISTER_TRANSFORM(TransformOptionalParensSimpleSelect); - REGISTER_TRANSFORM(TransformSimpleSelectParens); + // select.gram rules that remain manual after generated wrappers are registered. + Register("SelectStatementInternal", &TransformSelectStatementInternalRule); REGISTER_TRANSFORM(TransformSimpleSelect); - REGISTER_TRANSFORM(TransformSelectFrom); - REGISTER_TRANSFORM(TransformSelectFromClause); - REGISTER_TRANSFORM(TransformFromSelectClause); - REGISTER_TRANSFORM(TransformFromClause); - REGISTER_TRANSFORM(TransformSelectClause); - REGISTER_TRANSFORM(TransformDistinctClause); - REGISTER_TRANSFORM(TransformDistinctOn); - REGISTER_TRANSFORM(TransformDistinctOnTargets); - REGISTER_TRANSFORM(TransformDistinctAll); - REGISTER_TRANSFORM(TransformFunctionArgument); - REGISTER_TRANSFORM(TransformBaseTableName); - REGISTER_TRANSFORM(TransformSchemaReservedTable); - REGISTER_TRANSFORM(TransformCatalogReservedSchemaTable); - REGISTER_TRANSFORM(TransformWhereClause); - REGISTER_TRANSFORM(TransformTableFunctionArguments); - - REGISTER_TRANSFORM(TransformTargetList); - REGISTER_TRANSFORM(TransformAliasedExpression); - REGISTER_TRANSFORM(TransformExpressionAsCollabel); - REGISTER_TRANSFORM(TransformColIdExpression); - REGISTER_TRANSFORM(TransformExpressionOptIdentifier); - REGISTER_TRANSFORM(TransformTableAlias); - REGISTER_TRANSFORM(TransformTableAliasAs); - REGISTER_TRANSFORM(TransformTableAliasWithoutAs); - REGISTER_TRANSFORM(TransformColumnAliases); - REGISTER_TRANSFORM(TransformNamedParameter); + REGISTER_TRANSFORM(TransformDistinctOrAll); + REGISTER_TRANSFORM(TransformDistinctKeyword); + REGISTER_TRANSFORM(TransformAllKeyword); REGISTER_TRANSFORM(TransformTableRef); - - REGISTER_TRANSFORM(TransformOrderByClause); - REGISTER_TRANSFORM(TransformOrderByExpressions); - REGISTER_TRANSFORM(TransformOrderByExpressionList); - REGISTER_TRANSFORM(TransformOrderByAll); - REGISTER_TRANSFORM(TransformOrderByExpression); - REGISTER_TRANSFORM(TransformDescOrAsc); - REGISTER_TRANSFORM(TransformNullsFirstOrLast); - - REGISTER_TRANSFORM(TransformJoinOrPivot); - REGISTER_TRANSFORM(TransformJoinClause); - REGISTER_TRANSFORM(TransformRegularJoinClause); - REGISTER_TRANSFORM(TransformJoinType); - REGISTER_TRANSFORM(TransformJoinQualifier); - REGISTER_TRANSFORM(TransformOnClause); - REGISTER_TRANSFORM(TransformUsingClause); - REGISTER_TRANSFORM(TransformJoinWithoutOnClause); - REGISTER_TRANSFORM(TransformJoinPrefix); - REGISTER_TRANSFORM(TransformCrossJoinPrefix); - REGISTER_TRANSFORM(TransformNaturalJoinPrefix); - REGISTER_TRANSFORM(TransformPositionalJoinPrefix); - REGISTER_TRANSFORM(TransformTableUnpivotClause); - REGISTER_TRANSFORM(TransformUnpivotValueList); - REGISTER_TRANSFORM(TransformUnpivotTargetList); - - REGISTER_TRANSFORM(TransformTablePivotClause); - REGISTER_TRANSFORM(TransformPivotValueList); - REGISTER_TRANSFORM(TransformPivotHeader); - REGISTER_TRANSFORM(TransformPivotGroupByList); - REGISTER_TRANSFORM(TransformPivotTargetList); - - REGISTER_TRANSFORM(TransformInnerTableRef); - REGISTER_TRANSFORM(TransformTableFunction); - REGISTER_TRANSFORM(TransformTableFunctionLateralOpt); - REGISTER_TRANSFORM(TransformTableFunctionAliasColon); - REGISTER_TRANSFORM(TransformTableAliasColon); - REGISTER_TRANSFORM(TransformQualifiedTableFunction); - REGISTER_TRANSFORM(TransformTableSubquery); - REGISTER_TRANSFORM(TransformSubqueryReference); - REGISTER_TRANSFORM(TransformBaseTableRef); - REGISTER_TRANSFORM(TransformAtClause); - REGISTER_TRANSFORM(TransformAtSpecifier); - REGISTER_TRANSFORM(TransformAtUnit); - REGISTER_TRANSFORM(TransformValuesRef); - REGISTER_TRANSFORM(TransformValuesClause); - REGISTER_TRANSFORM(TransformValuesExpressions); - REGISTER_TRANSFORM(TransformTableStatement); - REGISTER_TRANSFORM(TransformParensTableRef); - - REGISTER_TRANSFORM(TransformResultModifiers); - REGISTER_TRANSFORM(TransformLimitOffset); - REGISTER_TRANSFORM(TransformLimitOffsetClause); - REGISTER_TRANSFORM(TransformOffsetLimitClause); - REGISTER_TRANSFORM(TransformLimitClause); - REGISTER_TRANSFORM(TransformLimitValue); - REGISTER_TRANSFORM(TransformLimitAll); - REGISTER_TRANSFORM(TransformLimitLiteralPercent); - REGISTER_TRANSFORM(TransformLimitExpression); - REGISTER_TRANSFORM(TransformOffsetClause); - REGISTER_TRANSFORM(TransformGroupByClause); - REGISTER_TRANSFORM(TransformGroupByExpressions); - REGISTER_TRANSFORM(TransformGroupByAll); - REGISTER_TRANSFORM(TransformGroupByList); - REGISTER_TRANSFORM(TransformGroupByExpression); - REGISTER_TRANSFORM(TransformEmptyGroupingItem); - REGISTER_TRANSFORM(TransformCubeOrRollupClause); - REGISTER_TRANSFORM(TransformGroupingSetsClause); - REGISTER_TRANSFORM(TransformWithClause); - REGISTER_TRANSFORM(TransformWithStatement); - REGISTER_TRANSFORM(TransformCTEBody); - REGISTER_TRANSFORM(TransformMaterialized); - REGISTER_TRANSFORM(TransformHavingClause); - REGISTER_TRANSFORM(TransformOffsetValue); - REGISTER_TRANSFORM(TransformQualifyClause); - REGISTER_TRANSFORM(TransformWindowClause); REGISTER_TRANSFORM(TransformWindowDefinition); - REGISTER_TRANSFORM(TransformUsingKey); - - REGISTER_TRANSFORM(TransformSampleClause); - REGISTER_TRANSFORM(TransformSampleEntry); - REGISTER_TRANSFORM(TransformSampleEntryFunction); - REGISTER_TRANSFORM(TransformSampleEntryCount); - REGISTER_TRANSFORM(TransformSampleCount); - REGISTER_TRANSFORM(TransformSampleValue); - REGISTER_TRANSFORM(TransformSampleUnit); - REGISTER_TRANSFORM(TransformSampleProperties); - REGISTER_TRANSFORM(TransformSampleSeed); - REGISTER_TRANSFORM(TransformSampleFunction); - REGISTER_TRANSFORM(TransformRepeatableSample); } void PEGTransformerFactory::RegisterKeywordsAndIdentifiers() { @@ -495,18 +371,6 @@ void PEGTransformerFactory::RegisterEnums() { RegisterEnum("PlusPrefixOperator", "+"); RegisterEnum("TildePrefixOperator", "~"); - RegisterEnum("DescendingOrder", OrderType::DESCENDING); - RegisterEnum("AscendingOrder", OrderType::ASCENDING); - RegisterEnum("NullsFirst", OrderByNullType::NULLS_FIRST); - RegisterEnum("NullsLast", OrderByNullType::NULLS_LAST); - - RegisterEnum("FullJoin", JoinType::OUTER); - RegisterEnum("LeftJoin", JoinType::LEFT); - RegisterEnum("RightJoin", JoinType::RIGHT); - RegisterEnum("SemiJoin", JoinType::SEMI); - RegisterEnum("AntiJoin", JoinType::ANTI); - RegisterEnum("InnerJoin", JoinType::INNER); - RegisterEnum("OperatorEqual", ExpressionType::COMPARE_EQUAL); RegisterEnum("OperatorNotEqual", ExpressionType::COMPARE_NOTEQUAL); RegisterEnum("OperatorLessThan", ExpressionType::COMPARE_LESSTHAN); @@ -514,9 +378,6 @@ void PEGTransformerFactory::RegisterEnums() { RegisterEnum("OperatorLessThanEquals", ExpressionType::COMPARE_LESSTHANOREQUALTO); RegisterEnum("OperatorGreaterThanEquals", ExpressionType::COMPARE_GREATERTHANOREQUALTO); - RegisterEnum("SetopUnion", SetOperationType::UNION); - RegisterEnum("SetopExcept", SetOperationType::EXCEPT); - RegisterEnum("TrimBoth", "trim"); RegisterEnum("TrimLeading", "ltrim"); RegisterEnum("TrimTrailing", "rtrim"); @@ -534,9 +395,6 @@ void PEGTransformerFactory::RegisterEnums() { RegisterEnum("ExcludeTies", WindowExcludeMode::TIES); RegisterEnum("ExcludeNoOthers", WindowExcludeMode::NO_OTHER); - RegisterEnum("SamplePercentage", true); - RegisterEnum("SampleRows", false); - RegisterEnum("SubqueryAny", true); RegisterEnum("SubqueryAll", false); diff --git a/src/duckdb/src/parser/peg/transformer/transform_common.cpp b/src/duckdb/src/parser/peg/transformer/transform_common.cpp index b3ebbd1fc..33e799813 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_common.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_common.cpp @@ -357,8 +357,7 @@ pair PEGTransformerFactory::TransformColIdType(PEGTrans unique_ptr PEGTransformerFactory::TransformBitType( PEGTransformer &transformer, - // NOLINTNEXTLINE(performance-unnecessary-value-param): fixed generated signature; BIT takes no modifiers - vector> expression) { + vector> expression) { // NOLINT(performance-unnecessary-value-param) return make_uniq(Identifier("BIT"), vector> {}); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_explain.cpp b/src/duckdb/src/parser/peg/transformer/transform_explain.cpp index 6a726808e..cd38816bf 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_explain.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_explain.cpp @@ -5,26 +5,12 @@ namespace duckdb { -ExplainFormat ParseExplainFormat(const Value &val) { +ProfilerPrintFormat ParseProfilerPrintFormat(const Value &val) { if (val.type().id() != LogicalTypeId::VARCHAR) { throw InvalidInputException("Expected a string as argument to FORMAT"); } - auto format_val = val.GetValue(); - case_insensitive_map_t format_mapping { - {"default", ExplainFormat::DEFAULT}, {"text", ExplainFormat::TEXT}, {"json", ExplainFormat::JSON}, - {"html", ExplainFormat::HTML}, {"graphviz", ExplainFormat::GRAPHVIZ}, {"yaml", ExplainFormat::YAML}, - {"mermaid", ExplainFormat::MERMAID}}; - auto it = format_mapping.find(format_val); - if (it != format_mapping.end()) { - return it->second; - } - vector options_list; - for (auto &format : format_mapping) { - options_list.push_back(format.first); - } - auto allowed_options = StringUtil::Join(options_list, ", "); - throw InvalidInputException("\"%s\" is not a valid FORMAT argument, valid options are: %s", format_val, - allowed_options); + // resolve the format name through the shared explain format registry (see main/profiler/profiler_print_format.hpp) + return ProfilerPrintFormat::FromString(val.GetValue()); } unique_ptr @@ -33,7 +19,7 @@ PEGTransformerFactory::TransformExplainStatement(PEGTransformer &transformer, co unique_ptr explainable_statements) { auto explain_type = explain_analyze ? ExplainType::EXPLAIN_ANALYZE : ExplainType::EXPLAIN_STANDARD; bool format_is_set = false; - auto explain_format = ExplainFormat::DEFAULT; + auto format = ProfilerPrintFormat::Default(); if (!explain_option_list.empty()) { for (auto option : explain_option_list) { auto option_name = StringUtil::Lower(option.name.GetIdentifierName()); @@ -41,7 +27,7 @@ PEGTransformerFactory::TransformExplainStatement(PEGTransformer &transformer, co if (format_is_set) { throw InvalidInputException("FORMAT can not be provided more than once"); } - explain_format = ParseExplainFormat(option.children[0]); + format = ParseProfilerPrintFormat(option.children[0]); format_is_set = true; } else if (option_name == "analyze") { explain_type = ExplainType::EXPLAIN_ANALYZE; @@ -51,7 +37,7 @@ PEGTransformerFactory::TransformExplainStatement(PEGTransformer &transformer, co } } auto statement = std::move(explainable_statements); - return make_uniq(std::move(statement), explain_type, explain_format); + return make_uniq(std::move(statement), explain_type, format); } bool PEGTransformerFactory::TransformExplainAnalyze(PEGTransformer &transformer) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_generated.cpp b/src/duckdb/src/parser/peg/transformer/transform_generated.cpp index 110fe9037..02b2ee294 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_generated.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_generated.cpp @@ -25,7 +25,8 @@ unique_ptr PEGTransformerFactory::TransformAlterTableStmtI bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto base_table_name = transformer.Transform>(list_pr.GetChild(2)); vector> alter_table_options; @@ -46,7 +47,8 @@ unique_ptr PEGTransformerFactory::TransformAlterSchemaStmt bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); auto rename_alter = transformer.Transform>(list_pr.GetChild(3)); @@ -76,7 +78,8 @@ unique_ptr PEGTransformerFactory::TransformAddColumnIntern bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto add_column_entry = transformer.Transform(list_pr.GetChild(3)); auto result = TransformAddColumn(transformer, if_not_exists, std::move(add_column_entry)); @@ -90,22 +93,27 @@ unique_ptr PEGTransformerFactory::TransformAddColumnEntryI LogicalType type {}; auto &type_opt = list_pr.GetChild(1).Cast(); if (type_opt.HasResult()) { - type = transformer.Transform(type_opt.GetResult()); + auto type_value = transformer.Transform(type_opt.GetResult()); + type = type_value; } GeneratedColumnDefinition generated_column {}; auto &generated_column_opt = list_pr.GetChild(2).Cast(); if (generated_column_opt.HasResult()) { - generated_column = transformer.Transform(generated_column_opt.GetResult()); + auto generated_column_value = + transformer.Transform(generated_column_opt.GetResult()); + generated_column = std::move(generated_column_value); } vector column_constraint {}; auto &column_constraint_opt = list_pr.GetChild(3).Cast(); if (column_constraint_opt.HasResult()) { - auto &column_constraint_repeat_1 = column_constraint_opt.GetResult().Cast(); - for (auto &column_constraint_item_1 : column_constraint_repeat_1.GetChildren()) { - auto column_constraint_value_1 = - transformer.Transform(column_constraint_item_1.get()); - column_constraint.push_back(std::move(column_constraint_value_1)); + vector column_constraint_value; + auto &column_constraint_value_repeat_1 = column_constraint_opt.GetResult().Cast(); + for (auto &column_constraint_value_item_1 : column_constraint_value_repeat_1.GetChildren()) { + auto column_constraint_value_value_1 = + transformer.Transform(column_constraint_value_item_1.get()); + column_constraint_value.push_back(std::move(column_constraint_value_value_1)); } + column_constraint = std::move(column_constraint_value); } auto result = TransformAddColumnEntry(transformer, dotted_identifier, type, std::move(generated_column), std::move(column_constraint)); @@ -118,13 +126,15 @@ unique_ptr PEGTransformerFactory::TransformDropColumnInter bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(2).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto nested_column_name = transformer.Transform>(list_pr.GetChild(3)); bool drop_behavior {}; auto &drop_behavior_opt = list_pr.GetChild(4).Cast(); if (drop_behavior_opt.HasResult()) { - drop_behavior = transformer.Transform(drop_behavior_opt.GetResult()); + auto drop_behavior_value = transformer.Transform(drop_behavior_opt.GetResult()); + drop_behavior = drop_behavior_value; } auto result = TransformDropColumn(transformer, if_exists, std::move(nested_column_name), drop_behavior); return make_uniq>>(std::move(result)); @@ -154,11 +164,13 @@ unique_ptr PEGTransformerFactory::TransformNestedColumnNam vector identifier_dot {}; auto &identifier_dot_opt = list_pr.GetChild(0).Cast(); if (identifier_dot_opt.HasResult()) { - auto &identifier_dot_repeat_1 = identifier_dot_opt.GetResult().Cast(); - for (auto &identifier_dot_item_1 : identifier_dot_repeat_1.GetChildren()) { - auto identifier_dot_value_1 = transformer.Transform(identifier_dot_item_1.get()); - identifier_dot.push_back(identifier_dot_value_1); + vector identifier_dot_value; + auto &identifier_dot_value_repeat_1 = identifier_dot_opt.GetResult().Cast(); + for (auto &identifier_dot_value_item_1 : identifier_dot_value_repeat_1.GetChildren()) { + auto identifier_dot_value_value_1 = transformer.Transform(identifier_dot_value_item_1.get()); + identifier_dot_value.push_back(identifier_dot_value_value_1); } + identifier_dot = identifier_dot_value; } auto column_name = list_pr.GetChild(1).Cast().identifier; auto result = TransformNestedColumnName(transformer, identifier_dot, column_name); @@ -297,12 +309,15 @@ unique_ptr PEGTransformerFactory::TransformAlterTypeIntern LogicalType type {}; auto &type_opt = list_pr.GetChild(2).Cast(); if (type_opt.HasResult()) { - type = transformer.Transform(type_opt.GetResult()); + auto type_value = transformer.Transform(type_opt.GetResult()); + type = type_value; } unique_ptr using_expression {}; auto &using_expression_opt = list_pr.GetChild(3).Cast(); if (using_expression_opt.HasResult()) { - using_expression = transformer.Transform>(using_expression_opt.GetResult()); + auto using_expression_value = + transformer.Transform>(using_expression_opt.GetResult()); + using_expression = std::move(using_expression_value); } auto result = TransformAlterType(transformer, type, std::move(using_expression)); return make_uniq>>(std::move(result)); @@ -322,7 +337,8 @@ unique_ptr PEGTransformerFactory::TransformAlterViewStmtIn bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto base_table_name = transformer.Transform>(list_pr.GetChild(2)); auto rename_alter = transformer.Transform>(list_pr.GetChild(3)); @@ -336,7 +352,8 @@ unique_ptr PEGTransformerFactory::TransformAlterSequenceSt bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto qualified_sequence_name = transformer.Transform(list_pr.GetChild(2)); auto alter_sequence_options = transformer.Transform>(list_pr.GetChild(3)); @@ -351,12 +368,14 @@ PEGTransformerFactory::TransformQualifiedSequenceNameInternal(PEGTransformer &tr Identifier catalog_qualification {}; auto &catalog_qualification_opt = list_pr.GetChild(0).Cast(); if (catalog_qualification_opt.HasResult()) { - catalog_qualification = transformer.Transform(catalog_qualification_opt.GetResult()); + auto catalog_qualification_value = transformer.Transform(catalog_qualification_opt.GetResult()); + catalog_qualification = catalog_qualification_value; } Identifier schema_qualification {}; auto &schema_qualification_opt = list_pr.GetChild(1).Cast(); if (schema_qualification_opt.HasResult()) { - schema_qualification = transformer.Transform(schema_qualification_opt.GetResult()); + auto schema_qualification_value = transformer.Transform(schema_qualification_opt.GetResult()); + schema_qualification = schema_qualification_value; } auto sequence_name = list_pr.GetChild(2).Cast().identifier; auto result = @@ -392,7 +411,8 @@ unique_ptr PEGTransformerFactory::TransformAlterDatabaseSt bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto identifier = list_pr.GetChild(2).Cast().identifier; auto identifier_1 = list_pr.GetChild(6).Cast().identifier; @@ -406,12 +426,14 @@ unique_ptr PEGTransformerFactory::TransformAnalyzeStatemen bool analyze_verbose {}; auto &analyze_verbose_opt = list_pr.GetChild(1).Cast(); if (analyze_verbose_opt.HasResult()) { - analyze_verbose = transformer.Transform(analyze_verbose_opt.GetResult()); + auto analyze_verbose_value = transformer.Transform(analyze_verbose_opt.GetResult()); + analyze_verbose = analyze_verbose_value; } AnalyzeTarget analyze_target {}; auto &analyze_target_opt = list_pr.GetChild(2).Cast(); if (analyze_target_opt.HasResult()) { - analyze_target = transformer.Transform(analyze_target_opt.GetResult()); + auto analyze_target_value = transformer.Transform(analyze_target_opt.GetResult()); + analyze_target = std::move(analyze_target_value); } auto result = TransformAnalyzeStatement(transformer, analyze_verbose, std::move(analyze_target)); return make_uniq>>(std::move(result)); @@ -424,7 +446,8 @@ unique_ptr PEGTransformerFactory::TransformAnalyzeTargetIn vector name_list {}; auto &name_list_opt = list_pr.GetChild(1).Cast(); if (name_list_opt.HasResult()) { - name_list = transformer.Transform>(name_list_opt.GetResult()); + auto name_list_value = transformer.Transform>(name_list_opt.GetResult()); + name_list = name_list_value; } auto result = TransformAnalyzeTarget(transformer, std::move(base_table_name), name_list); return make_uniq>(std::move(result)); @@ -442,23 +465,27 @@ unique_ptr PEGTransformerFactory::TransformAttachStatement bool or_replace {}; auto &or_replace_opt = list_pr.GetChild(1).Cast(); if (or_replace_opt.HasResult()) { - or_replace = transformer.Transform(or_replace_opt.GetResult()); + auto or_replace_value = transformer.Transform(or_replace_opt.GetResult()); + or_replace = or_replace_value; } bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto database_path = transformer.Transform>(list_pr.GetChild(4)); Identifier attach_alias {}; auto &attach_alias_opt = list_pr.GetChild(5).Cast(); if (attach_alias_opt.HasResult()) { - attach_alias = transformer.Transform(attach_alias_opt.GetResult()); + auto attach_alias_value = transformer.Transform(attach_alias_opt.GetResult()); + attach_alias = attach_alias_value; } vector attach_options {}; auto &attach_options_opt = list_pr.GetChild(6).Cast(); if (attach_options_opt.HasResult()) { - attach_options = transformer.Transform>(attach_options_opt.GetResult()); + auto attach_options_value = transformer.Transform>(attach_options_opt.GetResult()); + attach_options = attach_options_value; } auto result = TransformAttachStatement(transformer, or_replace, if_not_exists, std::move(database_path), attach_alias, attach_options); @@ -504,12 +531,14 @@ PEGTransformerFactory::TransformCheckpointStatementInternal(PEGTransformer &tran bool checkpoint_force {}; auto &checkpoint_force_opt = list_pr.GetChild(0).Cast(); if (checkpoint_force_opt.HasResult()) { - checkpoint_force = transformer.Transform(checkpoint_force_opt.GetResult()); + auto checkpoint_force_value = transformer.Transform(checkpoint_force_opt.GetResult()); + checkpoint_force = checkpoint_force_value; } Identifier catalog_name {}; auto &catalog_name_opt = list_pr.GetChild(2).Cast(); if (catalog_name_opt.HasResult()) { - catalog_name = catalog_name_opt.GetResult().Cast().identifier; + auto catalog_name_value = catalog_name_opt.GetResult().Cast().identifier; + catalog_name = catalog_name_value; } auto result = TransformCheckpointStatement(transformer, checkpoint_force, catalog_name); return make_uniq>>(std::move(result)); @@ -649,11 +678,13 @@ unique_ptr PEGTransformerFactory::TransformTypeInternal(PE vector array_bounds {}; auto &array_bounds_opt = list_pr.GetChild(1).Cast(); if (array_bounds_opt.HasResult()) { - auto &array_bounds_repeat_1 = array_bounds_opt.GetResult().Cast(); - for (auto &array_bounds_item_1 : array_bounds_repeat_1.GetChildren()) { - auto array_bounds_value_1 = transformer.Transform(array_bounds_item_1.get()); - array_bounds.push_back(array_bounds_value_1); + vector array_bounds_value; + auto &array_bounds_value_repeat_1 = array_bounds_opt.GetResult().Cast(); + for (auto &array_bounds_value_item_1 : array_bounds_value_repeat_1.GetChildren()) { + auto array_bounds_value_value_1 = transformer.Transform(array_bounds_value_item_1.get()); + array_bounds_value.push_back(array_bounds_value_value_1); } + array_bounds = array_bounds_value; } auto result = TransformType(transformer, std::move(type_variations), array_bounds); return make_uniq>(result); @@ -682,7 +713,9 @@ PEGTransformerFactory::TransformCharacterSimpleTypeInternal(PEGTransformer &tran vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } auto result = TransformCharacterSimpleType(transformer, character_type, std::move(type_modifiers)); return make_uniq>>(std::move(result)); @@ -695,7 +728,9 @@ PEGTransformerFactory::TransformQualifiedSimpleTypeInternal(PEGTransformer &tran vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } auto result = TransformQualifiedSimpleType(transformer, qualified_type_name, std::move(type_modifiers)); return make_uniq>>(std::move(result)); @@ -919,11 +954,15 @@ unique_ptr PEGTransformerFactory::TransformBitTypeInternal vector> expression {}; auto &expression_opt = list_pr.GetChild(2).Cast(); if (expression_opt.HasResult()) { - auto expression_items_1 = ExtractParseResultsFromList(ExtractResultFromParens(expression_opt.GetResult())); - for (auto &expression_item_1 : expression_items_1) { - auto expression_value_1 = transformer.Transform>(expression_item_1.get()); - expression.push_back(std::move(expression_value_1)); + vector> expression_value; + auto expression_value_items_1 = + ExtractParseResultsFromList(ExtractResultFromParens(expression_opt.GetResult())); + for (auto &expression_value_item_1 : expression_value_items_1) { + auto expression_value_value_1 = + transformer.Transform>(expression_value_item_1.get()); + expression_value.push_back(std::move(expression_value_value_1)); } + expression = std::move(expression_value); } auto result = TransformBitType(transformer, std::move(expression)); return make_uniq>>(std::move(result)); @@ -935,8 +974,9 @@ unique_ptr PEGTransformerFactory::TransformGeometryTypeInt unique_ptr expression {}; auto &expression_opt = list_pr.GetChild(1).Cast(); if (expression_opt.HasResult()) { - expression = + auto expression_value = transformer.Transform>(ExtractResultFromParens(expression_opt.GetResult())); + expression = std::move(expression_value); } auto result = TransformGeometryType(transformer, std::move(expression)); return make_uniq>>(std::move(result)); @@ -1031,8 +1071,9 @@ unique_ptr PEGTransformerFactory::TransformFloatTypeIntern unique_ptr number_literal {}; auto &number_literal_opt = list_pr.GetChild(1).Cast(); if (number_literal_opt.HasResult()) { - number_literal = transformer.Transform>( + auto number_literal_value = transformer.Transform>( ExtractResultFromParens(number_literal_opt.GetResult())); + number_literal = std::move(number_literal_value); } auto result = TransformFloatType(transformer, std::move(number_literal)); return make_uniq>>(std::move(result)); @@ -1044,7 +1085,9 @@ unique_ptr PEGTransformerFactory::TransformDecimalTypeInte vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } auto result = TransformDecimalType(transformer, std::move(type_modifiers)); return make_uniq>>(std::move(result)); @@ -1056,7 +1099,9 @@ unique_ptr PEGTransformerFactory::TransformDecTypeInternal vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } auto result = TransformDecType(transformer, std::move(type_modifiers)); return make_uniq>>(std::move(result)); @@ -1068,7 +1113,9 @@ unique_ptr PEGTransformerFactory::TransformNumericModTypeI vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } auto result = TransformNumericModType(transformer, std::move(type_modifiers)); return make_uniq>>(std::move(result)); @@ -1118,11 +1165,14 @@ unique_ptr PEGTransformerFactory::TransformTypeModifiersIn vector> expression {}; auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); if (expression_opt.HasResult()) { - auto expression_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_item_1 : expression_items_1) { - auto expression_value_1 = transformer.Transform>(expression_item_1.get()); - expression.push_back(std::move(expression_value_1)); + vector> expression_value; + auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); + for (auto &expression_value_item_1 : expression_value_items_1) { + auto expression_value_value_1 = + transformer.Transform>(expression_value_item_1.get()); + expression_value.push_back(std::move(expression_value_value_1)); } + expression = std::move(expression_value); } auto result = TransformTypeModifiers(transformer, std::move(expression)); return make_uniq>>>(std::move(result)); @@ -1207,7 +1257,8 @@ PEGTransformerFactory::TransformSquareBracketsArrayInternal(PEGTransformer &tran unique_ptr expression {}; auto &expression_opt = list_pr.GetChild(1).Cast(); if (expression_opt.HasResult()) { - expression = transformer.Transform>(expression_opt.GetResult()); + auto expression_value = transformer.Transform>(expression_opt.GetResult()); + expression = std::move(expression_value); } auto result = TransformSquareBracketsArray(transformer, std::move(expression)); return make_uniq>(result); @@ -1220,12 +1271,15 @@ unique_ptr PEGTransformerFactory::TransformTimeTypeInterna vector> type_modifiers {}; auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); if (type_modifiers_opt.HasResult()) { - type_modifiers = transformer.Transform>>(type_modifiers_opt.GetResult()); + auto type_modifiers_value = + transformer.Transform>>(type_modifiers_opt.GetResult()); + type_modifiers = std::move(type_modifiers_value); } bool time_zone {}; auto &time_zone_opt = list_pr.GetChild(2).Cast(); if (time_zone_opt.HasResult()) { - time_zone = transformer.Transform(time_zone_opt.GetResult()); + auto time_zone_value = transformer.Transform(time_zone_opt.GetResult()); + time_zone = time_zone_value; } auto result = TransformTimeType(transformer, time_or_timestamp, std::move(type_modifiers), time_zone); return make_uniq>>(std::move(result)); @@ -1308,14 +1362,16 @@ unique_ptr PEGTransformerFactory::TransformCopyTableIntern vector insert_column_list {}; auto &insert_column_list_opt = list_pr.GetChild(1).Cast(); if (insert_column_list_opt.HasResult()) { - insert_column_list = transformer.Transform>(insert_column_list_opt.GetResult()); + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; } auto from_or_to = transformer.Transform(list_pr.GetChild(2)); auto copy_file_name = transformer.Transform>(list_pr.GetChild(3)); vector copy_options {}; auto ©_options_opt = list_pr.GetChild(4).Cast(); if (copy_options_opt.HasResult()) { - copy_options = transformer.Transform>(copy_options_opt.GetResult()); + auto copy_options_value = transformer.Transform>(copy_options_opt.GetResult()); + copy_options = copy_options_value; } auto result = TransformCopyTable(transformer, std::move(base_table_name), insert_column_list, from_or_to, std::move(copy_file_name), copy_options); @@ -1351,7 +1407,8 @@ unique_ptr PEGTransformerFactory::TransformCopySelectInter vector copy_options {}; auto ©_options_opt = list_pr.GetChild(3).Cast(); if (copy_options_opt.HasResult()) { - copy_options = transformer.Transform>(copy_options_opt.GetResult()); + auto copy_options_value = transformer.Transform>(copy_options_opt.GetResult()); + copy_options = copy_options_value; } auto result = TransformCopySelect(transformer, std::move(select_statement_internal), std::move(copy_file_name), copy_options); @@ -1431,11 +1488,14 @@ PEGTransformerFactory::TransformSpecializedOptionListInternal(PEGTransformer &tr vector specialized_option {}; auto &specialized_option_opt = list_pr.GetChild(0).Cast(); if (specialized_option_opt.HasResult()) { - auto &specialized_option_repeat_1 = specialized_option_opt.GetResult().Cast(); - for (auto &specialized_option_item_1 : specialized_option_repeat_1.GetChildren()) { - auto specialized_option_value_1 = transformer.Transform(specialized_option_item_1.get()); - specialized_option.push_back(specialized_option_value_1); + vector specialized_option_value; + auto &specialized_option_value_repeat_1 = specialized_option_opt.GetResult().Cast(); + for (auto &specialized_option_value_item_1 : specialized_option_value_repeat_1.GetChildren()) { + auto specialized_option_value_value_1 = + transformer.Transform(specialized_option_value_item_1.get()); + specialized_option_value.push_back(specialized_option_value_value_1); } + specialized_option = specialized_option_value; } auto result = TransformSpecializedOptionList(transformer, specialized_option); return make_uniq>>(result); @@ -1533,7 +1593,8 @@ unique_ptr PEGTransformerFactory::TransformForceQuoteOptio bool force_quote {}; auto &force_quote_opt = list_pr.GetChild(0).Cast(); if (force_quote_opt.HasResult()) { - force_quote = transformer.Transform(force_quote_opt.GetResult()); + auto force_quote_value = transformer.Transform(force_quote_opt.GetResult()); + force_quote = force_quote_value; } auto star_symbol_column_list = transformer.Transform>(list_pr.GetChild(2)); auto result = TransformForceQuoteOption(transformer, force_quote, star_symbol_column_list); @@ -1572,7 +1633,8 @@ unique_ptr PEGTransformerFactory::TransformForceNullOption bool force_not_null {}; auto &force_not_null_opt = list_pr.GetChild(1).Cast(); if (force_not_null_opt.HasResult()) { - force_not_null = transformer.Transform(force_not_null_opt.GetResult()); + auto force_not_null_value = transformer.Transform(force_not_null_opt.GetResult()); + force_not_null = force_not_null_value; } auto column_list = transformer.Transform>(list_pr.GetChild(3)); auto result = TransformForceNullOption(transformer, force_not_null, column_list); @@ -1605,8 +1667,9 @@ unique_ptr PEGTransformerFactory::TransformGenericCopyOpti GenericCopyOptionValue generic_copy_option_value {}; auto &generic_copy_option_value_opt = list_pr.GetChild(1).Cast(); if (generic_copy_option_value_opt.HasResult()) { - generic_copy_option_value = + auto generic_copy_option_value_value = transformer.Transform(generic_copy_option_value_opt.GetResult()); + generic_copy_option_value = std::move(generic_copy_option_value_value); } auto result = TransformGenericCopyOption(transformer, copy_option_name, std::move(generic_copy_option_value)); return make_uniq>(result); @@ -1714,50 +1777,59 @@ unique_ptr PEGTransformerFactory::TransformCreateIndexStmt bool unique_index {}; auto &unique_index_opt = list_pr.GetChild(0).Cast(); if (unique_index_opt.HasResult()) { - unique_index = transformer.Transform(unique_index_opt.GetResult()); + auto unique_index_value = transformer.Transform(unique_index_opt.GetResult()); + unique_index = unique_index_value; } bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } Identifier index_name {}; auto &index_name_opt = list_pr.GetChild(3).Cast(); if (index_name_opt.HasResult()) { - index_name = index_name_opt.GetResult().Cast().identifier; + auto index_name_value = index_name_opt.GetResult().Cast().identifier; + index_name = index_name_value; } auto base_table_name = transformer.Transform>(list_pr.GetChild(5)); vector insert_column_list {}; auto &insert_column_list_opt = list_pr.GetChild(6).Cast(); if (insert_column_list_opt.HasResult()) { - insert_column_list = transformer.Transform>(insert_column_list_opt.GetResult()); + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; } Identifier index_type {}; auto &index_type_opt = list_pr.GetChild(7).Cast(); if (index_type_opt.HasResult()) { - index_type = transformer.Transform(index_type_opt.GetResult()); + auto index_type_value = transformer.Transform(index_type_opt.GetResult()); + index_type = index_type_value; } vector> index_element {}; auto &index_element_opt = list_pr.GetChild(8).Cast(); if (index_element_opt.HasResult()) { - auto index_element_items_1 = + vector> index_element_value; + auto index_element_value_items_1 = ExtractParseResultsFromList(ExtractResultFromParens(index_element_opt.GetResult())); - for (auto &index_element_item_1 : index_element_items_1) { - auto index_element_value_1 = - transformer.Transform>(index_element_item_1.get()); - index_element.push_back(std::move(index_element_value_1)); + for (auto &index_element_value_item_1 : index_element_value_items_1) { + auto index_element_value_value_1 = + transformer.Transform>(index_element_value_item_1.get()); + index_element_value.push_back(std::move(index_element_value_value_1)); } + index_element = std::move(index_element_value); } case_insensitive_map_t> with_list {}; auto &with_list_opt = list_pr.GetChild(9).Cast(); if (with_list_opt.HasResult()) { - with_list = + auto with_list_value = transformer.Transform>>(with_list_opt.GetResult()); + with_list = std::move(with_list_value); } unique_ptr where_clause {}; auto &where_clause_opt = list_pr.GetChild(10).Cast(); if (where_clause_opt.HasResult()) { - where_clause = transformer.Transform>(where_clause_opt.GetResult()); + auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); + where_clause = std::move(where_clause_value); } auto result = TransformCreateIndexStmt(transformer, unique_index, if_not_exists, index_name, std::move(base_table_name), insert_column_list, index_type, @@ -1831,12 +1903,14 @@ unique_ptr PEGTransformerFactory::TransformIndexElementInt OrderType desc_or_asc {}; auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); if (desc_or_asc_opt.HasResult()) { - desc_or_asc = transformer.Transform(desc_or_asc_opt.GetResult()); + auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); + desc_or_asc = desc_or_asc_value; } OrderByNullType nulls_first_or_last {}; auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); if (nulls_first_or_last_opt.HasResult()) { - nulls_first_or_last = transformer.Transform(nulls_first_or_last_opt.GetResult()); + auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); + nulls_first_or_last = nulls_first_or_last_value; } auto result = TransformIndexElement(transformer, std::move(expression), desc_or_asc, nulls_first_or_last); return make_uniq>>(std::move(result)); @@ -1863,8 +1937,9 @@ unique_ptr PEGTransformerFactory::TransformRelOptionIntern unique_ptr rel_option_argument_opt {}; auto &rel_option_argument_opt_opt = list_pr.GetChild(1).Cast(); if (rel_option_argument_opt_opt.HasResult()) { - rel_option_argument_opt = + auto rel_option_argument_opt_value = transformer.Transform>(rel_option_argument_opt_opt.GetResult()); + rel_option_argument_opt = std::move(rel_option_argument_opt_value); } auto result = TransformRelOption(transformer, rel_option_name, std::move(rel_option_argument_opt)); return make_uniq>>>(std::move(result)); @@ -1950,7 +2025,8 @@ unique_ptr PEGTransformerFactory::TransformCreateMacroStmt bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); vector> macro_definition; @@ -1990,7 +2066,8 @@ unique_ptr PEGTransformerFactory::TransformMacroDefinition vector macro_parameters {}; auto ¯o_parameters_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); if (macro_parameters_opt.HasResult()) { - macro_parameters = transformer.Transform>(macro_parameters_opt.GetResult()); + auto macro_parameters_value = transformer.Transform>(macro_parameters_opt.GetResult()); + macro_parameters = std::move(macro_parameters_value); } auto macro_definition_body = transformer.Transform>(list_pr.GetChild(2)); auto result = TransformMacroDefinition(transformer, std::move(macro_parameters), std::move(macro_definition_body)); @@ -2033,7 +2110,8 @@ unique_ptr PEGTransformerFactory::TransformSimpleParameter LogicalType type {}; auto &type_opt = list_pr.GetChild(1).Cast(); if (type_opt.HasResult()) { - type = transformer.Transform(type_opt.GetResult()); + auto type_value = transformer.Transform(type_opt.GetResult()); + type = type_value; } auto result = TransformSimpleParameter(transformer, type_func_name, type); return make_uniq>(std::move(result)); @@ -2061,7 +2139,8 @@ unique_ptr PEGTransformerFactory::TransformCreateSchemaStm bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); auto result = TransformCreateSchemaStmt(transformer, if_not_exists, qualified_name); @@ -2074,17 +2153,21 @@ unique_ptr PEGTransformerFactory::TransformCreateSecretStm bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } Identifier secret_name {}; auto &secret_name_opt = list_pr.GetChild(2).Cast(); if (secret_name_opt.HasResult()) { - secret_name = transformer.Transform(secret_name_opt.GetResult()); + auto secret_name_value = transformer.Transform(secret_name_opt.GetResult()); + secret_name = secret_name_value; } Identifier secret_storage_specifier {}; auto &secret_storage_specifier_opt = list_pr.GetChild(3).Cast(); if (secret_storage_specifier_opt.HasResult()) { - secret_storage_specifier = transformer.Transform(secret_storage_specifier_opt.GetResult()); + auto secret_storage_specifier_value = + transformer.Transform(secret_storage_specifier_opt.GetResult()); + secret_storage_specifier = secret_storage_specifier_value; } auto generic_copy_option_list = transformer.Transform>(list_pr.GetChild(4)); auto result = TransformCreateSecretStmt(transformer, if_not_exists, secret_name, secret_storage_specifier, @@ -2114,18 +2197,21 @@ unique_ptr PEGTransformerFactory::TransformCreateSequenceS bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); vector>> sequence_option {}; auto &sequence_option_opt = list_pr.GetChild(3).Cast(); if (sequence_option_opt.HasResult()) { - auto &sequence_option_repeat_1 = sequence_option_opt.GetResult().Cast(); - for (auto &sequence_option_item_1 : sequence_option_repeat_1.GetChildren()) { - auto sequence_option_value_1 = - transformer.Transform>>(sequence_option_item_1.get()); - sequence_option.push_back(std::move(sequence_option_value_1)); + vector>> sequence_option_value; + auto &sequence_option_value_repeat_1 = sequence_option_opt.GetResult().Cast(); + for (auto &sequence_option_value_item_1 : sequence_option_value_repeat_1.GetChildren()) { + auto sequence_option_value_value_1 = + transformer.Transform>>(sequence_option_value_item_1.get()); + sequence_option_value.push_back(std::move(sequence_option_value_value_1)); } + sequence_option = std::move(sequence_option_value); } auto result = TransformCreateSequenceStmt(transformer, if_not_exists, qualified_name, std::move(sequence_option)); return make_uniq>>(std::move(result)); @@ -2226,12 +2312,14 @@ unique_ptr PEGTransformerFactory::TransformCreateStatement bool or_replace {}; auto &or_replace_opt = list_pr.GetChild(1).Cast(); if (or_replace_opt.HasResult()) { - or_replace = transformer.Transform(or_replace_opt.GetResult()); + auto or_replace_value = transformer.Transform(or_replace_opt.GetResult()); + or_replace = or_replace_value; } SecretPersistType temporary {}; auto &temporary_opt = list_pr.GetChild(2).Cast(); if (temporary_opt.HasResult()) { - temporary = transformer.Transform(temporary_opt.GetResult()); + auto temporary_value = transformer.Transform(temporary_opt.GetResult()); + temporary = temporary_value; } auto create_statement_variation = transformer.Transform>(list_pr.GetChild(3)); auto result = TransformCreateStatement(transformer, or_replace, temporary, std::move(create_statement_variation)); @@ -2285,14 +2373,16 @@ unique_ptr PEGTransformerFactory::TransformCreateTableStmt bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); auto create_table_definition = transformer.Transform(list_pr.GetChild(3)); bool commit_action {}; auto &commit_action_opt = list_pr.GetChild(4).Cast(); if (commit_action_opt.HasResult()) { - commit_action = transformer.Transform(commit_action_opt.GetResult()); + auto commit_action_value = transformer.Transform(commit_action_opt.GetResult()); + commit_action = commit_action_value; } auto result = TransformCreateTableStmt(transformer, if_not_exists, qualified_name, std::move(create_table_definition), commit_action); @@ -2313,25 +2403,29 @@ unique_ptr PEGTransformerFactory::TransformCreateTableAsIn ColumnList identifier_list {}; auto &identifier_list_opt = list_pr.GetChild(0).Cast(); if (identifier_list_opt.HasResult()) { - identifier_list = transformer.Transform(identifier_list_opt.GetResult()); + auto identifier_list_value = transformer.Transform(identifier_list_opt.GetResult()); + identifier_list = std::move(identifier_list_value); } PartitionSortedOptions partition_sorted_options {}; auto &partition_sorted_options_opt = list_pr.GetChild(1).Cast(); if (partition_sorted_options_opt.HasResult()) { - partition_sorted_options = + auto partition_sorted_options_value = transformer.Transform(partition_sorted_options_opt.GetResult()); + partition_sorted_options = std::move(partition_sorted_options_value); } case_insensitive_map_t> with_list {}; auto &with_list_opt = list_pr.GetChild(2).Cast(); if (with_list_opt.HasResult()) { - with_list = + auto with_list_value = transformer.Transform>>(with_list_opt.GetResult()); + with_list = std::move(with_list_value); } auto statement = transformer.Transform>(list_pr.GetChild(4)); bool with_data {}; auto &with_data_opt = list_pr.GetChild(5).Cast(); if (with_data_opt.HasResult()) { - with_data = transformer.Transform(with_data_opt.GetResult()); + auto with_data_value = transformer.Transform(with_data_opt.GetResult()); + with_data = with_data_value; } auto result = TransformCreateTableAs(transformer, std::move(identifier_list), std::move(partition_sorted_options), std::move(with_list), std::move(statement), with_data); @@ -2354,7 +2448,9 @@ PEGTransformerFactory::TransformPartitionOptSortedOptionsInternal(PEGTransformer vector> sorted_options {}; auto &sorted_options_opt = list_pr.GetChild(1).Cast(); if (sorted_options_opt.HasResult()) { - sorted_options = transformer.Transform>>(sorted_options_opt.GetResult()); + auto sorted_options_value = + transformer.Transform>>(sorted_options_opt.GetResult()); + sorted_options = std::move(sorted_options_value); } auto result = TransformPartitionOptSortedOptions(transformer, std::move(partition_options), std::move(sorted_options)); @@ -2369,8 +2465,9 @@ PEGTransformerFactory::TransformSortedOptPartitionOptionsInternal(PEGTransformer vector> partition_options {}; auto &partition_options_opt = list_pr.GetChild(1).Cast(); if (partition_options_opt.HasResult()) { - partition_options = + auto partition_options_value = transformer.Transform>>(partition_options_opt.GetResult()); + partition_options = std::move(partition_options_value); } auto result = TransformSortedOptPartitionOptions(transformer, std::move(sorted_options), std::move(partition_options)); @@ -2442,19 +2539,23 @@ unique_ptr PEGTransformerFactory::TransformCreateColumnLis ColumnElements create_table_column_list {}; auto &create_table_column_list_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); if (create_table_column_list_opt.HasResult()) { - create_table_column_list = transformer.Transform(create_table_column_list_opt.GetResult()); + auto create_table_column_list_value = + transformer.Transform(create_table_column_list_opt.GetResult()); + create_table_column_list = std::move(create_table_column_list_value); } PartitionSortedOptions partition_sorted_options {}; auto &partition_sorted_options_opt = list_pr.GetChild(1).Cast(); if (partition_sorted_options_opt.HasResult()) { - partition_sorted_options = + auto partition_sorted_options_value = transformer.Transform(partition_sorted_options_opt.GetResult()); + partition_sorted_options = std::move(partition_sorted_options_value); } case_insensitive_map_t> with_list {}; auto &with_list_opt = list_pr.GetChild(2).Cast(); if (with_list_opt.HasResult()) { - with_list = + auto with_list_value = transformer.Transform>>(with_list_opt.GetResult()); + with_list = std::move(with_list_value); } auto result = TransformCreateColumnList(transformer, std::move(create_table_column_list), std::move(partition_sorted_options), std::move(with_list)); @@ -2625,22 +2726,27 @@ unique_ptr PEGTransformerFactory::TransformColumnDefinitio LogicalType type {}; auto &type_opt = list_pr.GetChild(1).Cast(); if (type_opt.HasResult()) { - type = transformer.Transform(type_opt.GetResult()); + auto type_value = transformer.Transform(type_opt.GetResult()); + type = type_value; } GeneratedColumnDefinition generated_column {}; auto &generated_column_opt = list_pr.GetChild(2).Cast(); if (generated_column_opt.HasResult()) { - generated_column = transformer.Transform(generated_column_opt.GetResult()); + auto generated_column_value = + transformer.Transform(generated_column_opt.GetResult()); + generated_column = std::move(generated_column_value); } vector column_constraint {}; auto &column_constraint_opt = list_pr.GetChild(4).Cast(); if (column_constraint_opt.HasResult()) { - auto &column_constraint_repeat_1 = column_constraint_opt.GetResult().Cast(); - for (auto &column_constraint_item_1 : column_constraint_repeat_1.GetChildren()) { - auto column_constraint_value_1 = - transformer.Transform(column_constraint_item_1.get()); - column_constraint.push_back(std::move(column_constraint_value_1)); + vector column_constraint_value; + auto &column_constraint_value_repeat_1 = column_constraint_opt.GetResult().Cast(); + for (auto &column_constraint_value_item_1 : column_constraint_value_repeat_1.GetChildren()) { + auto column_constraint_value_value_1 = + transformer.Transform(column_constraint_value_item_1.get()); + column_constraint_value.push_back(std::move(column_constraint_value_value_1)); } + column_constraint = std::move(column_constraint_value); } auto result = TransformColumnDefinition(transformer, dotted_identifier, type, std::move(generated_column), std::move(column_constraint)); @@ -2712,7 +2818,9 @@ PEGTransformerFactory::TransformForeignKeyConstraintInternal(PEGTransformer &tra vector column_list {}; auto &column_list_opt = list_pr.GetChild(2).Cast(); if (column_list_opt.HasResult()) { - column_list = transformer.Transform>(ExtractResultFromParens(column_list_opt.GetResult())); + auto column_list_value = + transformer.Transform>(ExtractResultFromParens(column_list_opt.GetResult())); + column_list = column_list_value; } auto key_actions = transformer.Transform(list_pr.GetChild(3)); auto result = TransformForeignKeyConstraint(transformer, std::move(base_table_name), column_list, key_actions); @@ -2741,12 +2849,14 @@ unique_ptr PEGTransformerFactory::TransformKeyActionsInter string update_action {}; auto &update_action_opt = list_pr.GetChild(0).Cast(); if (update_action_opt.HasResult()) { - update_action = transformer.Transform(update_action_opt.GetResult()); + auto update_action_value = transformer.Transform(update_action_opt.GetResult()); + update_action = update_action_value; } string delete_action {}; auto &delete_action_opt = list_pr.GetChild(1).Cast(); if (delete_action_opt.HasResult()) { - delete_action = transformer.Transform(delete_action_opt.GetResult()); + auto delete_action_value = transformer.Transform(delete_action_opt.GetResult()); + delete_action = delete_action_value; } auto result = TransformKeyActions(transformer, update_action, delete_action); return make_uniq>(result); @@ -2869,11 +2979,13 @@ unique_ptr PEGTransformerFactory::TransformDottedIdentifie vector dot_col_label {}; auto &dot_col_label_opt = list_pr.GetChild(1).Cast(); if (dot_col_label_opt.HasResult()) { - auto &dot_col_label_repeat_1 = dot_col_label_opt.GetResult().Cast(); - for (auto &dot_col_label_item_1 : dot_col_label_repeat_1.GetChildren()) { - auto dot_col_label_value_1 = transformer.Transform(dot_col_label_item_1.get()); - dot_col_label.push_back(dot_col_label_value_1); + vector dot_col_label_value; + auto &dot_col_label_value_repeat_1 = dot_col_label_opt.GetResult().Cast(); + for (auto &dot_col_label_value_item_1 : dot_col_label_value_repeat_1.GetChildren()) { + auto dot_col_label_value_value_1 = transformer.Transform(dot_col_label_value_item_1.get()); + dot_col_label_value.push_back(dot_col_label_value_value_1); } + dot_col_label = dot_col_label_value; } auto result = TransformDottedIdentifier(transformer, identifier, dot_col_label); return make_uniq>>(result); @@ -2936,7 +3048,8 @@ unique_ptr PEGTransformerFactory::TransformGeneratedColumn bool generated_column_type {}; auto &generated_column_type_opt = list_pr.GetChild(3).Cast(); if (generated_column_type_opt.HasResult()) { - generated_column_type = transformer.Transform(generated_column_type_opt.GetResult()); + auto generated_column_type_value = transformer.Transform(generated_column_type_opt.GetResult()); + generated_column_type = generated_column_type_value; } auto result = TransformGeneratedColumn(transformer, std::move(expression), generated_column_type); return make_uniq>(std::move(result)); @@ -2996,7 +3109,8 @@ unique_ptr PEGTransformerFactory::TransformCreateTriggerSt bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto trigger_name = transformer.Transform(list_pr.GetChild(2)); auto trigger_timing = transformer.Transform(list_pr.GetChild(3)); @@ -3005,12 +3119,15 @@ unique_ptr PEGTransformerFactory::TransformCreateTriggerSt TriggerTableReferencingInfo referencing_clause {}; auto &referencing_clause_opt = list_pr.GetChild(7).Cast(); if (referencing_clause_opt.HasResult()) { - referencing_clause = transformer.Transform(referencing_clause_opt.GetResult()); + auto referencing_clause_value = + transformer.Transform(referencing_clause_opt.GetResult()); + referencing_clause = referencing_clause_value; } TriggerForEach for_each_clause {}; auto &for_each_clause_opt = list_pr.GetChild(8).Cast(); if (for_each_clause_opt.HasResult()) { - for_each_clause = transformer.Transform(for_each_clause_opt.GetResult()); + auto for_each_clause_value = transformer.Transform(for_each_clause_opt.GetResult()); + for_each_clause = for_each_clause_value; } auto trigger_body = transformer.Transform>(list_pr.GetChild(9)); auto result = TransformCreateTriggerStmt(transformer, if_not_exists, trigger_name, trigger_timing, trigger_event, @@ -3042,7 +3159,9 @@ unique_ptr PEGTransformerFactory::TransformReferencingClau TriggerTableReferencingInfo referencing_item_1 {}; auto &referencing_item_1_opt = list_pr.GetChild(2).Cast(); if (referencing_item_1_opt.HasResult()) { - referencing_item_1 = transformer.Transform(referencing_item_1_opt.GetResult()); + auto referencing_item_1_value = + transformer.Transform(referencing_item_1_opt.GetResult()); + referencing_item_1 = referencing_item_1_value; } auto result = TransformReferencingClause(transformer, referencing_item, referencing_item_1); return make_uniq>(result); @@ -3171,7 +3290,8 @@ unique_ptr PEGTransformerFactory::TransformCreateTypeStmtI bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(2)); auto create_type = transformer.Transform>(list_pr.GetChild(4)); @@ -3210,11 +3330,13 @@ PEGTransformerFactory::TransformEnumStringLiteralListInternal(PEGTransformer &tr vector string_literal {}; auto &string_literal_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); if (string_literal_opt.HasResult()) { - auto string_literal_items_1 = ExtractParseResultsFromList(string_literal_opt.GetResult()); - for (auto &string_literal_item_1 : string_literal_items_1) { - auto string_literal_value_1 = transformer.Transform(string_literal_item_1.get()); - string_literal.push_back(string_literal_value_1); + vector string_literal_value; + auto string_literal_value_items_1 = ExtractParseResultsFromList(string_literal_opt.GetResult()); + for (auto &string_literal_value_item_1 : string_literal_value_items_1) { + auto string_literal_value_value_1 = transformer.Transform(string_literal_value_item_1.get()); + string_literal_value.push_back(string_literal_value_value_1); } + string_literal = string_literal_value; } auto result = TransformEnumStringLiteralList(transformer, string_literal); return make_uniq>>(std::move(result)); @@ -3226,24 +3348,28 @@ unique_ptr PEGTransformerFactory::TransformCreateViewStmtI bool create_recursive {}; auto &create_recursive_opt = list_pr.GetChild(0).Cast(); if (create_recursive_opt.HasResult()) { - create_recursive = transformer.Transform(create_recursive_opt.GetResult()); + auto create_recursive_value = transformer.Transform(create_recursive_opt.GetResult()); + create_recursive = create_recursive_value; } bool if_not_exists {}; auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); if (if_not_exists_opt.HasResult()) { - if_not_exists = transformer.Transform(if_not_exists_opt.GetResult()); + auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); + if_not_exists = if_not_exists_value; } auto qualified_name = transformer.Transform(list_pr.GetChild(3)); vector insert_column_list {}; auto &insert_column_list_opt = list_pr.GetChild(4).Cast(); if (insert_column_list_opt.HasResult()) { - insert_column_list = transformer.Transform>(insert_column_list_opt.GetResult()); + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; } case_insensitive_map_t> with_list {}; auto &with_list_opt = list_pr.GetChild(5).Cast(); if (with_list_opt.HasResult()) { - with_list = + auto with_list_value = transformer.Transform>>(with_list_opt.GetResult()); + with_list = std::move(with_list_value); } auto select_statement_internal = transformer.Transform>(list_pr.GetChild(7)); auto result = @@ -3264,7 +3390,8 @@ PEGTransformerFactory::TransformDeallocateStatementInternal(PEGTransformer &tran bool deallocate_prepare {}; auto &deallocate_prepare_opt = list_pr.GetChild(1).Cast(); if (deallocate_prepare_opt.HasResult()) { - deallocate_prepare = transformer.Transform(deallocate_prepare_opt.GetResult()); + auto deallocate_prepare_value = transformer.Transform(deallocate_prepare_opt.GetResult()); + deallocate_prepare = deallocate_prepare_value; } auto identifier = list_pr.GetChild(2).Cast().identifier; auto result = TransformDeallocateStatement(transformer, deallocate_prepare, identifier); @@ -3283,24 +3410,29 @@ unique_ptr PEGTransformerFactory::TransformDeleteStatement CommonTableExpressionMap with_clause {}; auto &with_clause_opt = list_pr.GetChild(0).Cast(); if (with_clause_opt.HasResult()) { - with_clause = transformer.Transform(with_clause_opt.GetResult()); + auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); + with_clause = std::move(with_clause_value); } auto target_opt_alias = transformer.Transform>(list_pr.GetChild(3)); vector> delete_using_clause {}; auto &delete_using_clause_opt = list_pr.GetChild(4).Cast(); if (delete_using_clause_opt.HasResult()) { - delete_using_clause = transformer.Transform>>(delete_using_clause_opt.GetResult()); + auto delete_using_clause_value = + transformer.Transform>>(delete_using_clause_opt.GetResult()); + delete_using_clause = std::move(delete_using_clause_value); } unique_ptr where_clause {}; auto &where_clause_opt = list_pr.GetChild(5).Cast(); if (where_clause_opt.HasResult()) { - where_clause = transformer.Transform>(where_clause_opt.GetResult()); + auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); + where_clause = std::move(where_clause_value); } vector> returning_clause {}; auto &returning_clause_opt = list_pr.GetChild(6).Cast(); if (returning_clause_opt.HasResult()) { - returning_clause = + auto returning_clause_value = transformer.Transform>>(returning_clause_opt.GetResult()); + returning_clause = std::move(returning_clause_value); } auto result = TransformDeleteStatement(transformer, std::move(with_clause), std::move(target_opt_alias), @@ -3323,7 +3455,8 @@ unique_ptr PEGTransformerFactory::TransformTargetOptAliasI Identifier col_id {}; auto &col_id_opt = list_pr.GetChild(2).Cast(); if (col_id_opt.HasResult()) { - col_id = transformer.Transform(col_id_opt.GetResult()); + auto col_id_value = transformer.Transform(col_id_opt.GetResult()); + col_id = col_id_value; } auto result = TransformTargetOptAlias(transformer, std::move(base_table_name), col_id); return make_uniq>>(std::move(result)); @@ -3375,7 +3508,8 @@ unique_ptr PEGTransformerFactory::TransformShowQualifiedNa DescribeTarget describe_target {}; auto &describe_target_opt = list_pr.GetChild(1).Cast(); if (describe_target_opt.HasResult()) { - describe_target = transformer.Transform(describe_target_opt.GetResult()); + auto describe_target_value = transformer.Transform(describe_target_opt.GetResult()); + describe_target = std::move(describe_target_value); } auto result = TransformShowQualifiedName(transformer, show_or_describe_or_summarize, std::move(describe_target)); return make_uniq>>(std::move(result)); @@ -3477,7 +3611,8 @@ unique_ptr PEGTransformerFactory::TransformDetachStatement bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(2).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto catalog_name = list_pr.GetChild(3).Cast().identifier; auto result = TransformDetachStatement(transformer, if_exists, catalog_name); @@ -3491,7 +3626,8 @@ unique_ptr PEGTransformerFactory::TransformDropStatementIn bool drop_behavior {}; auto &drop_behavior_opt = list_pr.GetChild(2).Cast(); if (drop_behavior_opt.HasResult()) { - drop_behavior = transformer.Transform(drop_behavior_opt.GetResult()); + auto drop_behavior_value = transformer.Transform(drop_behavior_opt.GetResult()); + drop_behavior = drop_behavior_value; } auto result = TransformDropStatement(transformer, std::move(drop_entries), drop_behavior); return make_uniq>>(std::move(result)); @@ -3511,7 +3647,8 @@ unique_ptr PEGTransformerFactory::TransformDropTriggerInte bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto trigger_name = transformer.Transform(list_pr.GetChild(2)); auto base_table_name = transformer.Transform>(list_pr.GetChild(4)); @@ -3526,7 +3663,8 @@ unique_ptr PEGTransformerFactory::TransformDropTableIntern bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector> base_table_name; auto base_table_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3545,7 +3683,8 @@ unique_ptr PEGTransformerFactory::TransformDropTableFuncti bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector table_function_name; auto table_function_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3564,7 +3703,8 @@ unique_ptr PEGTransformerFactory::TransformDropFunctionInt bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector function_identifier; auto function_identifier_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3582,7 +3722,8 @@ unique_ptr PEGTransformerFactory::TransformDropSchemaInter bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector qualified_schema_name; auto qualified_schema_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3600,7 +3741,8 @@ unique_ptr PEGTransformerFactory::TransformDropIndexIntern bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector qualified_index_name; auto qualified_index_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3656,7 +3798,8 @@ unique_ptr PEGTransformerFactory::TransformDropSequenceInt bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector qualified_sequence_name; auto qualified_sequence_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3674,7 +3817,8 @@ unique_ptr PEGTransformerFactory::TransformDropCollationIn bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector collation_name; auto collation_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3692,7 +3836,8 @@ unique_ptr PEGTransformerFactory::TransformDropTypeInterna bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(1).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } vector qualified_type_name; auto qualified_type_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); @@ -3710,18 +3855,21 @@ unique_ptr PEGTransformerFactory::TransformDropSecretInter SecretPersistType temporary {}; auto &temporary_opt = list_pr.GetChild(0).Cast(); if (temporary_opt.HasResult()) { - temporary = transformer.Transform(temporary_opt.GetResult()); + auto temporary_value = transformer.Transform(temporary_opt.GetResult()); + temporary = temporary_value; } bool if_exists {}; auto &if_exists_opt = list_pr.GetChild(2).Cast(); if (if_exists_opt.HasResult()) { - if_exists = transformer.Transform(if_exists_opt.GetResult()); + auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); + if_exists = if_exists_value; } auto secret_name = transformer.Transform(list_pr.GetChild(3)); Identifier drop_secret_storage {}; auto &drop_secret_storage_opt = list_pr.GetChild(4).Cast(); if (drop_secret_storage_opt.HasResult()) { - drop_secret_storage = transformer.Transform(drop_secret_storage_opt.GetResult()); + auto drop_secret_storage_value = transformer.Transform(drop_secret_storage_opt.GetResult()); + drop_secret_storage = drop_secret_storage_value; } auto result = TransformDropSecret(transformer, temporary, if_exists, secret_name, drop_secret_storage); return make_uniq>>(std::move(result)); @@ -3829,8 +3977,9 @@ unique_ptr PEGTransformerFactory::TransformExecuteStatemen vector table_function_arguments {}; auto &table_function_arguments_opt = list_pr.GetChild(2).Cast(); if (table_function_arguments_opt.HasResult()) { - table_function_arguments = + auto table_function_arguments_value = transformer.Transform>(table_function_arguments_opt.GetResult()); + table_function_arguments = std::move(table_function_arguments_value); } auto result = TransformExecuteStatement(transformer, identifier, std::move(table_function_arguments)); return make_uniq>>(std::move(result)); @@ -3842,12 +3991,15 @@ unique_ptr PEGTransformerFactory::TransformExplainStatemen bool explain_analyze {}; auto &explain_analyze_opt = list_pr.GetChild(1).Cast(); if (explain_analyze_opt.HasResult()) { - explain_analyze = transformer.Transform(explain_analyze_opt.GetResult()); + auto explain_analyze_value = transformer.Transform(explain_analyze_opt.GetResult()); + explain_analyze = explain_analyze_value; } vector explain_option_list {}; auto &explain_option_list_opt = list_pr.GetChild(2).Cast(); if (explain_option_list_opt.HasResult()) { - explain_option_list = transformer.Transform>(explain_option_list_opt.GetResult()); + auto explain_option_list_value = + transformer.Transform>(explain_option_list_opt.GetResult()); + explain_option_list = explain_option_list_value; } auto explainable_statements = transformer.Transform>(list_pr.GetChild(3)); auto result = @@ -3881,7 +4033,8 @@ unique_ptr PEGTransformerFactory::TransformExplainOptionIn unique_ptr expression {}; auto &expression_opt = list_pr.GetChild(1).Cast(); if (expression_opt.HasResult()) { - expression = transformer.Transform>(expression_opt.GetResult()); + auto expression_value = transformer.Transform>(expression_opt.GetResult()); + expression = std::move(expression_value); } auto result = TransformExplainOption(transformer, explain_option_name, std::move(expression)); return make_uniq>(result); @@ -3909,14 +4062,16 @@ unique_ptr PEGTransformerFactory::TransformExportStatement string export_source {}; auto &export_source_opt = list_pr.GetChild(2).Cast(); if (export_source_opt.HasResult()) { - export_source = transformer.Transform(export_source_opt.GetResult()); + auto export_source_value = transformer.Transform(export_source_opt.GetResult()); + export_source = export_source_value; } auto string_literal = transformer.Transform(list_pr.GetChild(3)); vector generic_copy_option_list {}; auto &generic_copy_option_list_opt = list_pr.GetChild(4).Cast(); if (generic_copy_option_list_opt.HasResult()) { - generic_copy_option_list = + auto generic_copy_option_list_value = transformer.Transform>(generic_copy_option_list_opt.GetResult()); + generic_copy_option_list = generic_copy_option_list_value; } auto result = TransformExportStatement(transformer, export_source, string_literal, generic_copy_option_list); return make_uniq>>(std::move(result)); @@ -3944,35 +4099,42 @@ unique_ptr PEGTransformerFactory::TransformInsertStatement CommonTableExpressionMap with_clause {}; auto &with_clause_opt = list_pr.GetChild(0).Cast(); if (with_clause_opt.HasResult()) { - with_clause = transformer.Transform(with_clause_opt.GetResult()); + auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); + with_clause = std::move(with_clause_value); } OnConflictAction or_action {}; auto &or_action_opt = list_pr.GetChild(2).Cast(); if (or_action_opt.HasResult()) { - or_action = transformer.Transform(or_action_opt.GetResult()); + auto or_action_value = transformer.Transform(or_action_opt.GetResult()); + or_action = or_action_value; } auto insert_target = transformer.Transform>(list_pr.GetChild(4)); InsertColumnOrder by_name_or_position {}; auto &by_name_or_position_opt = list_pr.GetChild(5).Cast(); if (by_name_or_position_opt.HasResult()) { - by_name_or_position = transformer.Transform(by_name_or_position_opt.GetResult()); + auto by_name_or_position_value = transformer.Transform(by_name_or_position_opt.GetResult()); + by_name_or_position = by_name_or_position_value; } vector insert_column_list {}; auto &insert_column_list_opt = list_pr.GetChild(6).Cast(); if (insert_column_list_opt.HasResult()) { - insert_column_list = transformer.Transform>(insert_column_list_opt.GetResult()); + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; } auto insert_values = transformer.Transform(list_pr.GetChild(7)); unique_ptr on_conflict_clause {}; auto &on_conflict_clause_opt = list_pr.GetChild(8).Cast(); if (on_conflict_clause_opt.HasResult()) { - on_conflict_clause = transformer.Transform>(on_conflict_clause_opt.GetResult()); + auto on_conflict_clause_value = + transformer.Transform>(on_conflict_clause_opt.GetResult()); + on_conflict_clause = std::move(on_conflict_clause_value); } vector> returning_clause {}; auto &returning_clause_opt = list_pr.GetChild(9).Cast(); if (returning_clause_opt.HasResult()) { - returning_clause = + auto returning_clause_value = transformer.Transform>>(returning_clause_opt.GetResult()); + returning_clause = std::move(returning_clause_value); } auto result = TransformInsertStatement(transformer, std::move(with_clause), or_action, std::move(insert_target), by_name_or_position, insert_column_list, std::move(insert_values), @@ -4043,7 +4205,8 @@ unique_ptr PEGTransformerFactory::TransformInsertTargetInt Identifier insert_alias {}; auto &insert_alias_opt = list_pr.GetChild(1).Cast(); if (insert_alias_opt.HasResult()) { - insert_alias = transformer.Transform(insert_alias_opt.GetResult()); + auto insert_alias_value = transformer.Transform(insert_alias_opt.GetResult()); + insert_alias = insert_alias_value; } auto result = TransformInsertTarget(transformer, std::move(base_table_name), insert_alias); return make_uniq>>(std::move(result)); @@ -4106,7 +4269,9 @@ unique_ptr PEGTransformerFactory::TransformOnConflictClaus OnConflictExpressionTarget on_conflict_target {}; auto &on_conflict_target_opt = list_pr.GetChild(2).Cast(); if (on_conflict_target_opt.HasResult()) { - on_conflict_target = transformer.Transform(on_conflict_target_opt.GetResult()); + auto on_conflict_target_value = + transformer.Transform(on_conflict_target_opt.GetResult()); + on_conflict_target = std::move(on_conflict_target_value); } auto on_conflict_action = transformer.Transform>(list_pr.GetChild(3)); auto result = TransformOnConflictClause(transformer, std::move(on_conflict_target), std::move(on_conflict_action)); @@ -4129,7 +4294,8 @@ PEGTransformerFactory::TransformOnConflictExpressionTargetInternal(PEGTransforme unique_ptr where_clause {}; auto &where_clause_opt = list_pr.GetChild(1).Cast(); if (where_clause_opt.HasResult()) { - where_clause = transformer.Transform>(where_clause_opt.GetResult()); + auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); + where_clause = std::move(where_clause_value); } auto result = TransformOnConflictExpressionTarget(transformer, column_id_list, std::move(where_clause)); return make_uniq>(std::move(result)); @@ -4158,7 +4324,8 @@ unique_ptr PEGTransformerFactory::TransformOnConflictUpdat unique_ptr where_clause {}; auto &where_clause_opt = list_pr.GetChild(4).Cast(); if (where_clause_opt.HasResult()) { - where_clause = transformer.Transform>(where_clause_opt.GetResult()); + auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); + where_clause = std::move(where_clause_value); } auto result = TransformOnConflictUpdate(transformer, std::move(update_set_clause), std::move(where_clause)); return make_uniq>>(std::move(result)); @@ -4185,7 +4352,8 @@ unique_ptr PEGTransformerFactory::TransformLoadStatementIn Identifier extension_alias {}; auto &extension_alias_opt = list_pr.GetChild(2).Cast(); if (extension_alias_opt.HasResult()) { - extension_alias = transformer.Transform(extension_alias_opt.GetResult()); + auto extension_alias_value = transformer.Transform(extension_alias_opt.GetResult()); + extension_alias = extension_alias_value; } auto result = TransformLoadStatement(transformer, col_id_or_string, extension_alias); return make_uniq>>(std::move(result)); @@ -4206,12 +4374,14 @@ unique_ptr PEGTransformerFactory::TransformInstallStatemen ExtensionRepositoryInfo from_source {}; auto &from_source_opt = list_pr.GetChild(3).Cast(); if (from_source_opt.HasResult()) { - from_source = transformer.Transform(from_source_opt.GetResult()); + auto from_source_value = transformer.Transform(from_source_opt.GetResult()); + from_source = from_source_value; } string version_number {}; auto &version_number_opt = list_pr.GetChild(4).Cast(); if (version_number_opt.HasResult()) { - version_number = transformer.Transform(version_number_opt.GetResult()); + auto version_number_value = transformer.Transform(version_number_opt.GetResult()); + version_number = version_number_value; } auto result = TransformInstallStatement(transformer, identifier_or_string_literal, from_source, version_number); return make_uniq>>(std::move(result)); @@ -4224,11 +4394,14 @@ PEGTransformerFactory::TransformUpdateExtensionsStatementInternal(PEGTransformer vector identifier {}; auto &identifier_opt = list_pr.GetChild(2).Cast(); if (identifier_opt.HasResult()) { - auto identifier_items_1 = ExtractParseResultsFromList(ExtractResultFromParens(identifier_opt.GetResult())); - for (auto &identifier_item_1 : identifier_items_1) { - auto identifier_value_1 = identifier_item_1.get().Cast().identifier; - identifier.push_back(identifier_value_1); + vector identifier_value; + auto identifier_value_items_1 = + ExtractParseResultsFromList(ExtractResultFromParens(identifier_opt.GetResult())); + for (auto &identifier_value_item_1 : identifier_value_items_1) { + auto identifier_value_value_1 = identifier_value_item_1.get().Cast().identifier; + identifier_value.push_back(identifier_value_value_1); } + identifier = identifier_value; } auto result = TransformUpdateExtensionsStatement(transformer, identifier); return make_uniq>>(std::move(result)); @@ -4272,7 +4445,8 @@ unique_ptr PEGTransformerFactory::TransformMergeIntoStatem CommonTableExpressionMap with_clause {}; auto &with_clause_opt = list_pr.GetChild(0).Cast(); if (with_clause_opt.HasResult()) { - with_clause = transformer.Transform(with_clause_opt.GetResult()); + auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); + with_clause = std::move(with_clause_value); } auto target_opt_alias = transformer.Transform>(list_pr.GetChild(3)); auto merge_into_using_clause = transformer.Transform>(list_pr.GetChild(4)); @@ -4287,8 +4461,9 @@ unique_ptr PEGTransformerFactory::TransformMergeIntoStatem vector> returning_clause {}; auto &returning_clause_opt = list_pr.GetChild(7).Cast(); if (returning_clause_opt.HasResult()) { - returning_clause = + auto returning_clause_value = transformer.Transform>>(returning_clause_opt.GetResult()); + returning_clause = std::move(returning_clause_value); } auto result = TransformMergeIntoStatement(transformer, std::move(with_clause), std::move(target_opt_alias), std::move(merge_into_using_clause), std::move(join_qualifier), @@ -4318,7 +4493,8 @@ unique_ptr PEGTransformerFactory::TransformMatchedClauseIn unique_ptr and_expression {}; auto &and_expression_opt = list_pr.GetChild(2).Cast(); if (and_expression_opt.HasResult()) { - and_expression = transformer.Transform>(and_expression_opt.GetResult()); + auto and_expression_value = transformer.Transform>(and_expression_opt.GetResult()); + and_expression = std::move(and_expression_value); } auto matched_clause_action = transformer.Transform>(list_pr.GetChild(4)); auto result = TransformMatchedClause(transformer, std::move(and_expression), std::move(matched_clause_action)); @@ -4339,7 +4515,9 @@ unique_ptr PEGTransformerFactory::TransformUpdateMatchClau unique_ptr update_match_info {}; auto &update_match_info_opt = list_pr.GetChild(1).Cast(); if (update_match_info_opt.HasResult()) { - update_match_info = transformer.Transform>(update_match_info_opt.GetResult()); + auto update_match_info_value = + transformer.Transform>(update_match_info_opt.GetResult()); + update_match_info = std::move(update_match_info_value); } auto result = TransformUpdateMatchClause(transformer, std::move(update_match_info)); return make_uniq>>(std::move(result)); @@ -4381,7 +4559,9 @@ unique_ptr PEGTransformerFactory::TransformInsertMatchClau unique_ptr insert_match_info {}; auto &insert_match_info_opt = list_pr.GetChild(1).Cast(); if (insert_match_info_opt.HasResult()) { - insert_match_info = transformer.Transform>(insert_match_info_opt.GetResult()); + auto insert_match_info_value = + transformer.Transform>(insert_match_info_opt.GetResult()); + insert_match_info = std::move(insert_match_info_value); } auto result = TransformInsertMatchClause(transformer, std::move(insert_match_info)); return make_uniq>>(std::move(result)); @@ -4407,7 +4587,8 @@ PEGTransformerFactory::TransformInsertByNameOrPositionInternal(PEGTransformer &t InsertColumnOrder by_name_or_position {}; auto &by_name_or_position_opt = list_pr.GetChild(0).Cast(); if (by_name_or_position_opt.HasResult()) { - by_name_or_position = transformer.Transform(by_name_or_position_opt.GetResult()); + auto by_name_or_position_value = transformer.Transform(by_name_or_position_opt.GetResult()); + by_name_or_position = by_name_or_position_value; } auto result = TransformInsertByNameOrPosition(transformer, by_name_or_position); return make_uniq>>(std::move(result)); @@ -4419,7 +4600,8 @@ unique_ptr PEGTransformerFactory::TransformInsertValuesLis vector insert_column_list {}; auto &insert_column_list_opt = list_pr.GetChild(0).Cast(); if (insert_column_list_opt.HasResult()) { - insert_column_list = transformer.Transform>(insert_column_list_opt.GetResult()); + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; } vector> expression; auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); @@ -4443,7 +4625,8 @@ unique_ptr PEGTransformerFactory::TransformErrorMatchClaus unique_ptr expression {}; auto &expression_opt = list_pr.GetChild(1).Cast(); if (expression_opt.HasResult()) { - expression = transformer.Transform>(expression_opt.GetResult()); + auto expression_value = transformer.Transform>(expression_opt.GetResult()); + expression = std::move(expression_value); } auto result = TransformErrorMatchClause(transformer, std::move(expression)); return make_uniq>>(std::move(result)); @@ -4483,12 +4666,15 @@ unique_ptr PEGTransformerFactory::TransformNotMatchedClaus MergeActionCondition by_source_or_target {}; auto &by_source_or_target_opt = list_pr.GetChild(3).Cast(); if (by_source_or_target_opt.HasResult()) { - by_source_or_target = transformer.Transform(by_source_or_target_opt.GetResult()); + auto by_source_or_target_value = + transformer.Transform(by_source_or_target_opt.GetResult()); + by_source_or_target = by_source_or_target_value; } unique_ptr and_expression {}; auto &and_expression_opt = list_pr.GetChild(4).Cast(); if (and_expression_opt.HasResult()) { - and_expression = transformer.Transform>(and_expression_opt.GetResult()); + auto and_expression_value = transformer.Transform>(and_expression_opt.GetResult()); + and_expression = std::move(and_expression_value); } auto matched_clause_action = transformer.Transform>(list_pr.GetChild(6)); auto result = TransformNotMatchedClause(transformer, by_source_or_target, std::move(and_expression), @@ -4667,8 +4853,9 @@ unique_ptr PEGTransformerFactory::TransformPragmaFunctionI vector> pragma_parameters {}; auto &pragma_parameters_opt = list_pr.GetChild(1).Cast(); if (pragma_parameters_opt.HasResult()) { - pragma_parameters = + auto pragma_parameters_value = transformer.Transform>>(pragma_parameters_opt.GetResult()); + pragma_parameters = std::move(pragma_parameters_value); } auto result = TransformPragmaFunction(transformer, pragma_name, std::move(pragma_parameters)); return make_uniq>>(std::move(result)); @@ -4694,7 +4881,8 @@ unique_ptr PEGTransformerFactory::TransformPrepareStatemen vector type_list {}; auto &type_list_opt = list_pr.GetChild(2).Cast(); if (type_list_opt.HasResult()) { - type_list = transformer.Transform>(type_list_opt.GetResult()); + auto type_list_value = transformer.Transform>(type_list_opt.GetResult()); + type_list = type_list_value; } auto statement = transformer.Transform>(list_pr.GetChild(4)); auto result = TransformPrepareStatement(transformer, identifier, type_list, std::move(statement)); @@ -4714,6 +4902,1652 @@ unique_ptr PEGTransformerFactory::TransformTypeListInterna return make_uniq>>(result); } +unique_ptr PEGTransformerFactory::TransformSelectStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_statement_internal = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformSelectStatement(transformer, std::move(select_statement_internal)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSelectSetOpChainInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto intersect_chain = transformer.Transform>(list_pr.GetChild(0)); + optional, unique_ptr>>> select_set_op_chain_tail {}; + auto &select_set_op_chain_tail_opt = list_pr.GetChild(1).Cast(); + if (select_set_op_chain_tail_opt.HasResult()) { + vector, unique_ptr>> select_set_op_chain_tail_value; + auto &select_set_op_chain_tail_value_repeat_1 = + select_set_op_chain_tail_opt.GetResult().Cast(); + for (auto &select_set_op_chain_tail_value_item_1 : select_set_op_chain_tail_value_repeat_1.GetChildren()) { + auto select_set_op_chain_tail_value_value_1 = + transformer.Transform, unique_ptr>>( + select_set_op_chain_tail_value_item_1.get()); + select_set_op_chain_tail_value.push_back(std::move(select_set_op_chain_tail_value_value_1)); + } + select_set_op_chain_tail = std::move(select_set_op_chain_tail_value); + } + auto result = + TransformSelectSetOpChain(transformer, std::move(intersect_chain), std::move(select_set_op_chain_tail)); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformSelectSetOpChainTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto setop_clause = transformer.Transform>(list_pr.GetChild(0)); + auto intersect_chain = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformSelectSetOpChainTail(transformer, std::move(setop_clause), std::move(intersect_chain)); + return make_uniq, unique_ptr>>>( + std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformIntersectChainInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_atom = transformer.Transform>(list_pr.GetChild(0)); + optional, unique_ptr>>> intersect_chain_tail {}; + auto &intersect_chain_tail_opt = list_pr.GetChild(1).Cast(); + if (intersect_chain_tail_opt.HasResult()) { + vector, unique_ptr>> intersect_chain_tail_value; + auto &intersect_chain_tail_value_repeat_1 = intersect_chain_tail_opt.GetResult().Cast(); + for (auto &intersect_chain_tail_value_item_1 : intersect_chain_tail_value_repeat_1.GetChildren()) { + auto intersect_chain_tail_value_value_1 = + transformer.Transform, unique_ptr>>( + intersect_chain_tail_value_item_1.get()); + intersect_chain_tail_value.push_back(std::move(intersect_chain_tail_value_value_1)); + } + intersect_chain_tail = std::move(intersect_chain_tail_value); + } + auto result = TransformIntersectChain(transformer, std::move(select_atom), std::move(intersect_chain_tail)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformIntersectChainTailInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto set_intersect_clause = transformer.Transform>(list_pr.GetChild(0)); + auto select_atom = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformIntersectChainTail(transformer, std::move(set_intersect_clause), std::move(select_atom)); + return make_uniq, unique_ptr>>>( + std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSetIntersectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional distinct_or_all {}; + auto &distinct_or_all_opt = list_pr.GetChild(1).Cast(); + if (distinct_or_all_opt.HasResult()) { + auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); + distinct_or_all = distinct_or_all_value; + } + auto result = TransformSetIntersectClause(transformer, distinct_or_all); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSelectAtomInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSelectParensInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_statement_internal = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformSelectParens(transformer, std::move(select_statement_internal)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSetopClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto setop_type = transformer.Transform(list_pr.GetChild(0)); + optional distinct_or_all {}; + auto &distinct_or_all_opt = list_pr.GetChild(1).Cast(); + if (distinct_or_all_opt.HasResult()) { + auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); + distinct_or_all = distinct_or_all_value; + } + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(2).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformSetopClause(transformer, setop_type, distinct_or_all, has_result); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSetopTypeInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSetopUnionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformSetopUnion(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSetopExceptInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformSetopExcept(transformer); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformSelectStatementTypeInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformResultModifiersInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional> order_by_clause {}; + auto &order_by_clause_opt = list_pr.GetChild(0).Cast(); + if (order_by_clause_opt.HasResult()) { + auto order_by_clause_value = transformer.Transform>(order_by_clause_opt.GetResult()); + order_by_clause = std::move(order_by_clause_value); + } + optional> limit_offset {}; + auto &limit_offset_opt = list_pr.GetChild(1).Cast(); + if (limit_offset_opt.HasResult()) { + auto limit_offset_value = transformer.Transform>(limit_offset_opt.GetResult()); + limit_offset = std::move(limit_offset_value); + } + auto result = TransformResultModifiers(transformer, std::move(order_by_clause), std::move(limit_offset)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitOffsetInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitOffsetClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto limit_clause = transformer.Transform(list_pr.GetChild(0)); + optional offset_clause {}; + auto &offset_clause_opt = list_pr.GetChild(1).Cast(); + if (offset_clause_opt.HasResult()) { + auto offset_clause_value = transformer.Transform(offset_clause_opt.GetResult()); + offset_clause = std::move(offset_clause_value); + } + auto result = TransformLimitOffsetClause(transformer, std::move(limit_clause), std::move(offset_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOffsetLimitClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto offset_clause = transformer.Transform(list_pr.GetChild(0)); + optional limit_clause {}; + auto &limit_clause_opt = list_pr.GetChild(1).Cast(); + if (limit_clause_opt.HasResult()) { + auto limit_clause_value = transformer.Transform(limit_clause_opt.GetResult()); + limit_clause = std::move(limit_clause_value); + } + auto result = TransformOffsetLimitClause(transformer, std::move(offset_clause), std::move(limit_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTableStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto base_table_name = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformTableStatement(transformer, std::move(base_table_name)); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformOptionalParensSimpleSelectInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSimpleSelectParensInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto simple_select = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformSimpleSelectParens(transformer, std::move(simple_select)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSelectFromInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSelectFromClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_clause = transformer.Transform>(list_pr.GetChild(0)); + optional> from_clause {}; + auto &from_clause_opt = list_pr.GetChild(1).Cast(); + if (from_clause_opt.HasResult()) { + auto from_clause_value = transformer.Transform>(from_clause_opt.GetResult()); + from_clause = std::move(from_clause_value); + } + auto result = TransformSelectFromClause(transformer, std::move(select_clause), std::move(from_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformFromSelectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto from_clause = transformer.Transform>(list_pr.GetChild(0)); + optional> select_clause {}; + auto &select_clause_opt = list_pr.GetChild(1).Cast(); + if (select_clause_opt.HasResult()) { + auto select_clause_value = transformer.Transform>(select_clause_opt.GetResult()); + select_clause = std::move(select_clause_value); + } + auto result = TransformFromSelectClause(transformer, std::move(from_clause), std::move(select_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformWithStatementInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); + optional> insert_column_list {}; + auto &insert_column_list_opt = list_pr.GetChild(1).Cast(); + if (insert_column_list_opt.HasResult()) { + auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); + insert_column_list = insert_column_list_value; + } + optional>> using_key {}; + auto &using_key_opt = list_pr.GetChild(2).Cast(); + if (using_key_opt.HasResult()) { + auto using_key_value = transformer.Transform>>(using_key_opt.GetResult()); + using_key = std::move(using_key_value); + } + optional materialized {}; + auto &materialized_opt = list_pr.GetChild(4).Cast(); + if (materialized_opt.HasResult()) { + auto materialized_value = transformer.Transform(materialized_opt.GetResult()); + materialized = materialized_value; + } + auto cte_body = transformer.Transform>(list_pr.GetChild(5)); + auto result = TransformWithStatement(transformer, col_id_or_string, insert_column_list, std::move(using_key), + materialized, std::move(cte_body)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformCTEBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformCTESelectBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_statement_internal = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformCTESelectBody(transformer, std::move(select_statement_internal)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformCTEDMLBodyInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto statement = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformCTEDMLBody(transformer, std::move(statement)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformUsingKeyInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto target_list = + transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(2))); + auto result = TransformUsingKey(transformer, std::move(target_list)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformMaterializedInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(0).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformMaterialized(transformer, has_result); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSelectClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional distinct_clause {}; + auto &distinct_clause_opt = list_pr.GetChild(1).Cast(); + if (distinct_clause_opt.HasResult()) { + auto distinct_clause_value = transformer.Transform(distinct_clause_opt.GetResult()); + distinct_clause = std::move(distinct_clause_value); + } + optional>> target_list {}; + auto &target_list_opt = list_pr.GetChild(2).Cast(); + if (target_list_opt.HasResult()) { + auto target_list_value = + transformer.Transform>>(target_list_opt.GetResult()); + target_list = std::move(target_list_value); + } + auto result = TransformSelectClause(transformer, std::move(distinct_clause), std::move(target_list)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector> aliased_expression; + auto aliased_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); + for (auto &aliased_expression_item : aliased_expression_items) { + auto aliased_expression_value = + transformer.Transform>(aliased_expression_item.get()); + aliased_expression.push_back(std::move(aliased_expression_value)); + } + auto result = TransformTargetList(transformer, std::move(aliased_expression)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformColumnAliasesInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector col_id_or_string; + auto col_id_or_string_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); + for (auto &col_id_or_string_item : col_id_or_string_items) { + auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); + col_id_or_string.push_back(col_id_or_string_value); + } + auto result = TransformColumnAliases(transformer, col_id_or_string); + return make_uniq>>(result); +} + +unique_ptr PEGTransformerFactory::TransformDistinctClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformDistinctAllInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformDistinctAll(transformer); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformDistinctOnInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional>> distinct_on_targets {}; + auto &distinct_on_targets_opt = list_pr.GetChild(1).Cast(); + if (distinct_on_targets_opt.HasResult()) { + auto distinct_on_targets_value = + transformer.Transform>>(distinct_on_targets_opt.GetResult()); + distinct_on_targets = std::move(distinct_on_targets_value); + } + auto result = TransformDistinctOn(transformer, std::move(distinct_on_targets)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformDistinctOnTargetsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector> expression; + auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); + for (auto &expression_item : expression_items) { + auto expression_value = transformer.Transform>(expression_item.get()); + expression.push_back(std::move(expression_value)); + } + auto result = TransformDistinctOnTargets(transformer, std::move(expression)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformInnerTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTableSubqueryInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional lateral {}; + auto &lateral_opt = list_pr.GetChild(0).Cast(); + if (lateral_opt.HasResult()) { + auto lateral_value = transformer.Transform(lateral_opt.GetResult()); + lateral = lateral_value; + } + auto subquery_reference = transformer.Transform>(list_pr.GetChild(1)); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(2).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + auto result = TransformTableSubquery(transformer, lateral, std::move(subquery_reference), table_alias); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformBaseTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional table_alias_colon {}; + auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); + if (table_alias_colon_opt.HasResult()) { + auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); + table_alias_colon = table_alias_colon_value; + } + auto base_table_name = transformer.Transform>(list_pr.GetChild(1)); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(2).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + optional> at_clause {}; + auto &at_clause_opt = list_pr.GetChild(3).Cast(); + if (at_clause_opt.HasResult()) { + auto at_clause_value = transformer.Transform>(at_clause_opt.GetResult()); + at_clause = std::move(at_clause_value); + } + optional> sample_clause {}; + auto &sample_clause_opt = list_pr.GetChild(4).Cast(); + if (sample_clause_opt.HasResult()) { + auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); + sample_clause = std::move(sample_clause_value); + } + auto result = TransformBaseTableRef(transformer, table_alias_colon, std::move(base_table_name), table_alias, + std::move(at_clause), std::move(sample_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTableAliasColonInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); + auto result = TransformTableAliasColon(transformer, col_id_or_string); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformValuesRefInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto values_clause = transformer.Transform>(list_pr.GetChild(0)); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(1).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + auto result = TransformValuesRef(transformer, std::move(values_clause), table_alias); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformParensTableRefInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional table_alias_colon {}; + auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); + if (table_alias_colon_opt.HasResult()) { + auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); + table_alias_colon = table_alias_colon_value; + } + auto table_ref = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(2).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + optional> sample_clause {}; + auto &sample_clause_opt = list_pr.GetChild(3).Cast(); + if (sample_clause_opt.HasResult()) { + auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); + sample_clause = std::move(sample_clause_value); + } + auto result = TransformParensTableRef(transformer, table_alias_colon, std::move(table_ref), table_alias, + std::move(sample_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformJoinOrPivotInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTablePivotClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto table_pivot_clause_body = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(2).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + auto result = TransformTablePivotClause(transformer, std::move(table_pivot_clause_body), table_alias); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformTablePivotClauseBodyInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto target_list = transformer.Transform>>(list_pr.GetChild(0)); + vector pivot_value_list; + auto &pivot_value_list_repeat = list_pr.GetChild(2).Cast(); + for (auto &pivot_value_list_item : pivot_value_list_repeat.GetChildren()) { + auto pivot_value_list_value = transformer.Transform(pivot_value_list_item.get()); + pivot_value_list.push_back(std::move(pivot_value_list_value)); + } + optional> pivot_group_by_list {}; + auto &pivot_group_by_list_opt = list_pr.GetChild(3).Cast(); + if (pivot_group_by_list_opt.HasResult()) { + auto pivot_group_by_list_value = transformer.Transform>(pivot_group_by_list_opt.GetResult()); + pivot_group_by_list = pivot_group_by_list_value; + } + auto result = TransformTablePivotClauseBody(transformer, std::move(target_list), std::move(pivot_value_list), + pivot_group_by_list); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformPivotGroupByListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector col_id_or_string; + auto col_id_or_string_items = ExtractParseResultsFromList(list_pr.GetChild(2)); + for (auto &col_id_or_string_item : col_id_or_string_items) { + auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); + col_id_or_string.push_back(col_id_or_string_value); + } + auto result = TransformPivotGroupByList(transformer, col_id_or_string); + return make_uniq>>(result); +} + +unique_ptr PEGTransformerFactory::TransformTableUnpivotClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional include_or_exclude_nulls {}; + auto &include_or_exclude_nulls_opt = list_pr.GetChild(1).Cast(); + if (include_or_exclude_nulls_opt.HasResult()) { + auto include_or_exclude_nulls_value = transformer.Transform(include_or_exclude_nulls_opt.GetResult()); + include_or_exclude_nulls = include_or_exclude_nulls_value; + } + auto table_unpivot_clause_body = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(3).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + auto result = TransformTableUnpivotClause(transformer, include_or_exclude_nulls, + std::move(table_unpivot_clause_body), table_alias); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformTableUnpivotClauseBodyInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto unpivot_header = transformer.Transform>(list_pr.GetChild(0)); + vector unpivot_value_list; + auto &unpivot_value_list_repeat = list_pr.GetChild(2).Cast(); + for (auto &unpivot_value_list_item : unpivot_value_list_repeat.GetChildren()) { + auto unpivot_value_list_value = transformer.Transform(unpivot_value_list_item.get()); + unpivot_value_list.push_back(std::move(unpivot_value_list_value)); + } + auto result = TransformTableUnpivotClauseBody(transformer, unpivot_header, std::move(unpivot_value_list)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformPivotHeaderInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto base_expression = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformPivotHeader(transformer, std::move(base_expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformPivotValueListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto pivot_header = transformer.Transform>(list_pr.GetChild(0)); + auto pivot_value_target = transformer.Transform(list_pr.GetChild(2)); + auto result = TransformPivotValueList(transformer, std::move(pivot_header), std::move(pivot_value_target)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformPivotValueTargetInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = TransformPivotValueTarget(transformer, choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformUnpivotValueListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto unpivot_header = transformer.Transform>(list_pr.GetChild(0)); + auto unpivot_target_list = transformer.Transform>(list_pr.GetChild(2)); + auto result = TransformUnpivotValueList(transformer, unpivot_header, std::move(unpivot_target_list)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformPivotTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto target_list = + transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformPivotTargetList(transformer, std::move(target_list)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformUnpivotTargetListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto target_list = + transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformUnpivotTargetList(transformer, std::move(target_list)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLateralInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformLateral(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformBaseTableNameInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformUnqualifiedBaseTableNameInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto table_name = list_pr.GetChild(0).Cast().identifier; + auto result = TransformUnqualifiedBaseTableName(transformer, table_name); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformSchemaReservedTableInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); + auto reserved_table_name = list_pr.GetChild(1).Cast().identifier; + auto result = TransformSchemaReservedTable(transformer, schema_qualification, reserved_table_name); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformCatalogReservedSchemaTableInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); + auto reserved_schema_qualification = transformer.Transform(list_pr.GetChild(1)); + auto reserved_table_name = list_pr.GetChild(2).Cast().identifier; + auto result = TransformCatalogReservedSchemaTable(transformer, catalog_qualification, reserved_schema_qualification, + reserved_table_name); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTableFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformTableFunctionLateralOptInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional lateral {}; + auto &lateral_opt = list_pr.GetChild(0).Cast(); + if (lateral_opt.HasResult()) { + auto lateral_value = transformer.Transform(lateral_opt.GetResult()); + lateral = lateral_value; + } + auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); + auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); + optional with_ordinality {}; + auto &with_ordinality_opt = list_pr.GetChild(3).Cast(); + if (with_ordinality_opt.HasResult()) { + auto with_ordinality_value = transformer.Transform(with_ordinality_opt.GetResult()); + with_ordinality = with_ordinality_value; + } + optional table_alias {}; + auto &table_alias_opt = list_pr.GetChild(4).Cast(); + if (table_alias_opt.HasResult()) { + auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); + table_alias = table_alias_value; + } + auto result = TransformTableFunctionLateralOpt(transformer, lateral, qualified_table_function, + std::move(table_function_arguments), with_ordinality, table_alias); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformTableFunctionAliasColonInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto table_alias_colon = transformer.Transform(list_pr.GetChild(0)); + auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); + auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); + optional with_ordinality {}; + auto &with_ordinality_opt = list_pr.GetChild(3).Cast(); + if (with_ordinality_opt.HasResult()) { + auto with_ordinality_value = transformer.Transform(with_ordinality_opt.GetResult()); + with_ordinality = with_ordinality_value; + } + optional> sample_clause {}; + auto &sample_clause_opt = list_pr.GetChild(4).Cast(); + if (sample_clause_opt.HasResult()) { + auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); + sample_clause = std::move(sample_clause_value); + } + auto result = TransformTableFunctionAliasColon(transformer, table_alias_colon, qualified_table_function, + std::move(table_function_arguments), with_ordinality, + std::move(sample_clause)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformWithOrdinalityInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformWithOrdinality(transformer); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformQualifiedTableFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional catalog_qualification {}; + auto &catalog_qualification_opt = list_pr.GetChild(0).Cast(); + if (catalog_qualification_opt.HasResult()) { + auto catalog_qualification_value = transformer.Transform(catalog_qualification_opt.GetResult()); + catalog_qualification = catalog_qualification_value; + } + optional schema_qualification {}; + auto &schema_qualification_opt = list_pr.GetChild(1).Cast(); + if (schema_qualification_opt.HasResult()) { + auto schema_qualification_value = transformer.Transform(schema_qualification_opt.GetResult()); + schema_qualification = schema_qualification_value; + } + auto table_function_name = list_pr.GetChild(2).Cast().identifier; + auto result = + TransformQualifiedTableFunction(transformer, catalog_qualification, schema_qualification, table_function_name); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformTableFunctionArgumentsInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional> function_argument {}; + auto &function_argument_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); + if (function_argument_opt.HasResult()) { + vector function_argument_value; + auto function_argument_value_items_1 = ExtractParseResultsFromList(function_argument_opt.GetResult()); + for (auto &function_argument_value_item_1 : function_argument_value_items_1) { + auto function_argument_value_value_1 = + transformer.Transform(function_argument_value_item_1.get()); + function_argument_value.push_back(std::move(function_argument_value_value_1)); + } + function_argument = std::move(function_argument_value); + } + auto result = TransformTableFunctionArguments(transformer, std::move(function_argument)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformFunctionArgumentInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformNamedFunctionArgumentInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto named_parameter = transformer.Transform(list_pr.GetChild(0)); + auto result = TransformNamedFunctionArgument(transformer, std::move(named_parameter)); + return make_uniq>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformPositionalFunctionArgumentInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformPositionalFunctionArgument(transformer, std::move(expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformNamedParameterInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto type_func_name = transformer.Transform(list_pr.GetChild(0)); + optional type {}; + auto &type_opt = list_pr.GetChild(1).Cast(); + if (type_opt.HasResult()) { + auto type_value = transformer.Transform(type_opt.GetResult()); + type = type_value; + } + auto expression = transformer.Transform>(list_pr.GetChild(3)); + auto result = TransformNamedParameter(transformer, type_func_name, type, std::move(expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformTableAliasInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformTableAliasAsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto identifier_or_string_literal = transformer.Transform(list_pr.GetChild(1)); + optional> column_aliases {}; + auto &column_aliases_opt = list_pr.GetChild(2).Cast(); + if (column_aliases_opt.HasResult()) { + auto column_aliases_value = transformer.Transform>(column_aliases_opt.GetResult()); + column_aliases = column_aliases_value; + } + auto result = TransformTableAliasAs(transformer, identifier_or_string_literal, column_aliases); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformTableAliasWithoutAsInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto identifier = list_pr.GetChild(0).Cast().identifier; + optional> column_aliases {}; + auto &column_aliases_opt = list_pr.GetChild(1).Cast(); + if (column_aliases_opt.HasResult()) { + auto column_aliases_value = transformer.Transform>(column_aliases_opt.GetResult()); + column_aliases = column_aliases_value; + } + auto result = TransformTableAliasWithoutAs(transformer, identifier, column_aliases); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformAtClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto at_specifier = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); + auto result = TransformAtClause(transformer, std::move(at_specifier)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformAtSpecifierInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto at_unit = transformer.Transform(list_pr.GetChild(0)); + auto expression = transformer.Transform>(list_pr.GetChild(2)); + auto result = TransformAtSpecifier(transformer, at_unit, std::move(expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformVersionAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformVersionAtUnit(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformTimestampAtUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformTimestampAtUnit(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformJoinClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformRegularJoinClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional asof {}; + auto &asof_opt = list_pr.GetChild(0).Cast(); + if (asof_opt.HasResult()) { + auto asof_value = transformer.Transform(asof_opt.GetResult()); + asof = asof_value; + } + optional join_type {}; + auto &join_type_opt = list_pr.GetChild(1).Cast(); + if (join_type_opt.HasResult()) { + auto join_type_value = transformer.Transform(join_type_opt.GetResult()); + join_type = join_type_value; + } + auto table_ref = transformer.Transform>(list_pr.GetChild(3)); + auto join_qualifier = transformer.Transform(list_pr.GetChild(4)); + auto result = + TransformRegularJoinClause(transformer, asof, join_type, std::move(table_ref), std::move(join_qualifier)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformAsofInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformAsof(transformer); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformJoinWithoutOnClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto join_prefix = transformer.Transform(list_pr.GetChild(0)); + auto table_ref = transformer.Transform>(list_pr.GetChild(2)); + auto result = TransformJoinWithoutOnClause(transformer, join_prefix, std::move(table_ref)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformJoinQualifierInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOnClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformOnClause(transformer, std::move(expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformUsingClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector column_name; + auto column_name_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); + for (auto &column_name_item : column_name_items) { + auto column_name_value = column_name_item.get().Cast().identifier; + column_name.push_back(column_name_value); + } + auto result = TransformUsingClause(transformer, column_name); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformJoinTypeInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformCrossJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformCrossJoinPrefix(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformNaturalJoinPrefixInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional join_type {}; + auto &join_type_opt = list_pr.GetChild(1).Cast(); + if (join_type_opt.HasResult()) { + auto join_type_value = transformer.Transform(join_type_opt.GetResult()); + join_type = join_type_value; + } + auto result = TransformNaturalJoinPrefix(transformer, join_type); + return make_uniq>(result); +} + +unique_ptr +PEGTransformerFactory::TransformPositionalJoinPrefixInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto result = TransformPositionalJoinPrefix(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformFullJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(1).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformFullJoin(transformer, has_result); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformLeftJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(1).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformLeftJoin(transformer, has_result); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformRightJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(1).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformRightJoin(transformer, has_result); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSemiJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformSemiJoin(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformAntiJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformAntiJoin(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformInnerJoinInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformInnerJoin(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformFromClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector> table_ref; + auto table_ref_items = ExtractParseResultsFromList(list_pr.GetChild(1)); + for (auto &table_ref_item : table_ref_items) { + auto table_ref_value = transformer.Transform>(table_ref_item.get()); + table_ref.push_back(std::move(table_ref_value)); + } + auto result = TransformFromClause(transformer, std::move(table_ref)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformWhereClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformWhereClause(transformer, std::move(expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformGroupByClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto group_by_expressions = transformer.Transform(list_pr.GetChild(2)); + auto result = TransformGroupByClause(transformer, std::move(group_by_expressions)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformHavingClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformHavingClause(transformer, std::move(expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformQualifyClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformQualifyClause(transformer, std::move(expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto sample_entry = transformer.Transform>(list_pr.GetChild(1)); + auto result = TransformSampleClause(transformer, std::move(sample_entry)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformWindowClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector> window_definition; + auto window_definition_items = ExtractParseResultsFromList(list_pr.GetChild(1)); + for (auto &window_definition_item : window_definition_items) { + auto window_definition_value = + transformer.Transform>(window_definition_item.get()); + window_definition.push_back(std::move(window_definition_value)); + } + auto result = TransformWindowClause(transformer, std::move(window_definition)); + return make_uniq>>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleEntryInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleEntryCountInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto sample_count = transformer.Transform>(list_pr.GetChild(0)); + optional> sample_properties {}; + auto &sample_properties_opt = list_pr.GetChild(1).Cast(); + if (sample_properties_opt.HasResult()) { + auto sample_properties_value = transformer.Transform>( + ExtractResultFromParens(sample_properties_opt.GetResult())); + sample_properties = sample_properties_value; + } + auto result = TransformSampleEntryCount(transformer, std::move(sample_count), sample_properties); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformSampleEntryFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional sample_function {}; + auto &sample_function_opt = list_pr.GetChild(0).Cast(); + if (sample_function_opt.HasResult()) { + auto sample_function_value = transformer.Transform(sample_function_opt.GetResult()); + sample_function = sample_function_value; + } + auto sample_count = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); + optional repeatable_sample {}; + auto &repeatable_sample_opt = list_pr.GetChild(2).Cast(); + if (repeatable_sample_opt.HasResult()) { + auto repeatable_sample_value = transformer.Transform(repeatable_sample_opt.GetResult()); + repeatable_sample = repeatable_sample_value; + } + auto result = + TransformSampleEntryFunction(transformer, sample_function, std::move(sample_count), repeatable_sample); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleFunctionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto col_id = transformer.Transform(list_pr.GetChild(0)); + auto result = TransformSampleFunction(transformer, col_id); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSamplePropertiesInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto col_id = transformer.Transform(list_pr.GetChild(0)); + optional sample_seed {}; + auto &sample_seed_opt = list_pr.GetChild(1).Cast(); + if (sample_seed_opt.HasResult()) { + auto sample_seed_value = + transformer.Transform(sample_seed_opt.GetResult().Cast().GetChild(1)); + sample_seed = sample_seed_value; + } + auto result = TransformSampleProperties(transformer, col_id, sample_seed); + return make_uniq>>(result); +} + +unique_ptr PEGTransformerFactory::TransformRepeatableSampleInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto sample_seed = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(1))); + auto result = TransformRepeatableSample(transformer, sample_seed); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSampleSeedInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto number_literal = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformSampleSeed(transformer, std::move(number_literal)); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSampleCountInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto sample_value = transformer.Transform>(list_pr.GetChild(0)); + optional sample_unit {}; + auto &sample_unit_opt = list_pr.GetChild(1).Cast(); + if (sample_unit_opt.HasResult()) { + auto sample_unit_value = transformer.Transform(sample_unit_opt.GetResult()); + sample_unit = sample_unit_value; + } + auto result = TransformSampleCount(transformer, std::move(sample_value), sample_unit); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleValueInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSampleUnitInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSamplePercentageInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformSamplePercentage(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformSampleRowsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformSampleRows(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformGroupByExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformGroupByAllInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformGroupByAll(transformer); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformGroupByListInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector group_by_expression; + auto group_by_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); + for (auto &group_by_expression_item : group_by_expression_items) { + auto group_by_expression_value = transformer.Transform(group_by_expression_item.get()); + group_by_expression.push_back(std::move(group_by_expression_value)); + } + auto result = TransformGroupByList(transformer, std::move(group_by_expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformGroupByExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformGroupByBaseExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformGroupByBaseExpression(transformer, std::move(expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformEmptyGroupingItemInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformEmptyGroupingItem(transformer); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformCubeOrRollupClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto cube_or_rollup = transformer.Transform(list_pr.GetChild(0)); + optional>> expression {}; + auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); + if (expression_opt.HasResult()) { + vector> expression_value; + auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); + for (auto &expression_value_item_1 : expression_value_items_1) { + auto expression_value_value_1 = + transformer.Transform>(expression_value_item_1.get()); + expression_value.push_back(std::move(expression_value_value_1)); + } + expression = std::move(expression_value); + } + auto result = TransformCubeOrRollupClause(transformer, cube_or_rollup, std::move(expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformCubeOrRollupInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformCubeKeywordInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformCubeKeyword(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformRollupKeywordInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformRollupKeyword(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformGroupingSetsClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector group_by_expression; + auto group_by_expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); + for (auto &group_by_expression_item : group_by_expression_items) { + auto group_by_expression_value = transformer.Transform(group_by_expression_item.get()); + group_by_expression.push_back(std::move(group_by_expression_value)); + } + auto result = TransformGroupingSetsClause(transformer, std::move(group_by_expression)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformSubqueryReferenceInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto select_statement_internal = + transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); + auto result = TransformSubqueryReference(transformer, std::move(select_statement_internal)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOrderByExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + optional desc_or_asc {}; + auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); + if (desc_or_asc_opt.HasResult()) { + auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); + desc_or_asc = desc_or_asc_value; + } + optional nulls_first_or_last {}; + auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); + if (nulls_first_or_last_opt.HasResult()) { + auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); + nulls_first_or_last = nulls_first_or_last_value; + } + auto result = TransformOrderByExpression(transformer, std::move(expression), desc_or_asc, nulls_first_or_last); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformDescOrAscInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformDescendingOrderInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformDescendingOrder(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformAscendingOrderInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformAscendingOrder(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformNullsFirstOrLastInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformNullsFirstInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformNullsFirst(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformNullsLastInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformNullsLast(transformer); + return make_uniq>(result); +} + +unique_ptr PEGTransformerFactory::TransformOrderByClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto order_by_expressions = transformer.Transform>(list_pr.GetChild(2)); + auto result = TransformOrderByClause(transformer, std::move(order_by_expressions)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOrderByExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformOrderByExpressionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector order_by_expression; + auto order_by_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); + for (auto &order_by_expression_item : order_by_expression_items) { + auto order_by_expression_value = transformer.Transform(order_by_expression_item.get()); + order_by_expression.push_back(std::move(order_by_expression_value)); + } + auto result = TransformOrderByExpressionList(transformer, std::move(order_by_expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOrderByAllInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + optional desc_or_asc {}; + auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); + if (desc_or_asc_opt.HasResult()) { + auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); + desc_or_asc = desc_or_asc_value; + } + optional nulls_first_or_last {}; + auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); + if (nulls_first_or_last_opt.HasResult()) { + auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); + nulls_first_or_last = nulls_first_or_last_value; + } + auto result = TransformOrderByAll(transformer, desc_or_asc, nulls_first_or_last); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto limit_value = transformer.Transform(list_pr.GetChild(1)); + auto result = TransformLimitClause(transformer, std::move(limit_value)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOffsetClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto offset_value = transformer.Transform(list_pr.GetChild(1)); + auto result = TransformOffsetClause(transformer, std::move(offset_value)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformOffsetValueInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(1).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformOffsetValue(transformer, std::move(expression), has_result); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitValueInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform(choice_pr.GetResult()); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitAllInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto result = TransformLimitAll(transformer); + return make_uniq>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformLimitLiteralPercentInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto number_literal = transformer.Transform>(list_pr.GetChild(0)); + auto result = TransformLimitLiteralPercent(transformer, std::move(number_literal)); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformLimitExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + bool has_result {}; + auto &has_result_opt = list_pr.GetChild(1).Cast(); + has_result = has_result_opt.HasResult(); + auto result = TransformLimitExpression(transformer, std::move(expression), has_result); + return make_uniq>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformAliasedExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto result = transformer.Transform>(choice_pr.GetResult()); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformColIdExpressionInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto col_id = transformer.Transform(list_pr.GetChild(0)); + auto expression = transformer.Transform>(list_pr.GetChild(2)); + auto result = TransformColIdExpression(transformer, col_id, std::move(expression)); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformExpressionAsCollabelInternal(PEGTransformer &transformer, ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + auto col_label_or_string = transformer.Transform(list_pr.GetChild(2)); + auto result = TransformExpressionAsCollabel(transformer, std::move(expression), col_label_or_string); + return make_uniq>>(std::move(result)); +} + +unique_ptr +PEGTransformerFactory::TransformExpressionOptIdentifierInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + auto expression = transformer.Transform>(list_pr.GetChild(0)); + optional identifier {}; + auto &identifier_opt = list_pr.GetChild(1).Cast(); + if (identifier_opt.HasResult()) { + auto identifier_value = identifier_opt.GetResult().Cast().identifier; + identifier = identifier_value; + } + auto result = TransformExpressionOptIdentifier(transformer, std::move(expression), identifier); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformValuesClauseInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector>> values_expressions; + auto values_expressions_items = ExtractParseResultsFromList(list_pr.GetChild(1)); + for (auto &values_expressions_item : values_expressions_items) { + auto values_expressions_value = + transformer.Transform>>(values_expressions_item.get()); + values_expressions.push_back(std::move(values_expressions_value)); + } + auto result = TransformValuesClause(transformer, std::move(values_expressions)); + return make_uniq>>(std::move(result)); +} + +unique_ptr PEGTransformerFactory::TransformValuesExpressionsInternal(PEGTransformer &transformer, + ParseResult &parse_result) { + auto &list_pr = parse_result.Cast(); + vector> expression; + auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); + for (auto &expression_item : expression_items) { + auto expression_value = transformer.Transform>(expression_item.get()); + expression.push_back(std::move(expression_value)); + } + auto result = TransformValuesExpressions(transformer, std::move(expression)); + return make_uniq>>>(std::move(result)); +} + unique_ptr PEGTransformerFactory::TransformSetStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { auto &list_pr = parse_result.Cast(); @@ -4808,7 +6642,8 @@ PEGTransformerFactory::TransformZoneIntervalWithIntervalInternal(PEGTransformer DatePartSpecifier interval {}; auto &interval_opt = list_pr.GetChild(2).Cast(); if (interval_opt.HasResult()) { - interval = transformer.Transform(interval_opt.GetResult()); + auto interval_value = transformer.Transform(interval_opt.GetResult()); + interval = interval_value; } auto result = TransformZoneIntervalWithInterval(transformer, string_literal, interval); return make_uniq>>(std::move(result)); @@ -4831,7 +6666,8 @@ unique_ptr PEGTransformerFactory::TransformSetSettingInter SetScope setting_scope {}; auto &setting_scope_opt = list_pr.GetChild(0).Cast(); if (setting_scope_opt.HasResult()) { - setting_scope = transformer.Transform(setting_scope_opt.GetResult()); + auto setting_scope_value = transformer.Transform(setting_scope_opt.GetResult()); + setting_scope = setting_scope_value; } auto setting_name = list_pr.GetChild(1).Cast().identifier; auto result = TransformSetSetting(transformer, setting_scope, setting_name); @@ -4914,7 +6750,8 @@ unique_ptr PEGTransformerFactory::TransformBeginTransactio TransactionModifierType read_or_write {}; auto &read_or_write_opt = list_pr.GetChild(2).Cast(); if (read_or_write_opt.HasResult()) { - read_or_write = transformer.Transform(read_or_write_opt.GetResult()); + auto read_or_write_value = transformer.Transform(read_or_write_opt.GetResult()); + read_or_write = read_or_write_value; } auto result = TransformBeginTransaction(transformer, read_or_write); return make_uniq>>(std::move(result)); @@ -4966,25 +6803,29 @@ unique_ptr PEGTransformerFactory::TransformUpdateStatement CommonTableExpressionMap with_clause {}; auto &with_clause_opt = list_pr.GetChild(0).Cast(); if (with_clause_opt.HasResult()) { - with_clause = transformer.Transform(with_clause_opt.GetResult()); + auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); + with_clause = std::move(with_clause_value); } auto update_target = transformer.Transform>(list_pr.GetChild(2)); auto update_set_clause = transformer.Transform>(list_pr.GetChild(3)); unique_ptr from_clause {}; auto &from_clause_opt = list_pr.GetChild(4).Cast(); if (from_clause_opt.HasResult()) { - from_clause = transformer.Transform>(from_clause_opt.GetResult()); + auto from_clause_value = transformer.Transform>(from_clause_opt.GetResult()); + from_clause = std::move(from_clause_value); } unique_ptr where_clause {}; auto &where_clause_opt = list_pr.GetChild(5).Cast(); if (where_clause_opt.HasResult()) { - where_clause = transformer.Transform>(where_clause_opt.GetResult()); + auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); + where_clause = std::move(where_clause_value); } vector> returning_clause {}; auto &returning_clause_opt = list_pr.GetChild(6).Cast(); if (returning_clause_opt.HasResult()) { - returning_clause = + auto returning_clause_value = transformer.Transform>>(returning_clause_opt.GetResult()); + returning_clause = std::move(returning_clause_value); } auto result = TransformUpdateStatement(transformer, std::move(with_clause), std::move(update_target), std::move(update_set_clause), std::move(from_clause), @@ -5015,7 +6856,8 @@ unique_ptr PEGTransformerFactory::TransformBaseTableAliasS Identifier update_alias {}; auto &update_alias_opt = list_pr.GetChild(1).Cast(); if (update_alias_opt.HasResult()) { - update_alias = transformer.Transform(update_alias_opt.GetResult()); + auto update_alias_value = transformer.Transform(update_alias_opt.GetResult()); + update_alias = update_alias_value; } auto result = TransformBaseTableAliasSet(transformer, std::move(base_table_name), update_alias); return make_uniq>>(std::move(result)); @@ -5081,11 +6923,13 @@ PEGTransformerFactory::TransformUpdateSetColumnTargetInternal(PEGTransformer &tr vector dot_identifier {}; auto &dot_identifier_opt = list_pr.GetChild(1).Cast(); if (dot_identifier_opt.HasResult()) { - auto &dot_identifier_repeat_1 = dot_identifier_opt.GetResult().Cast(); - for (auto &dot_identifier_item_1 : dot_identifier_repeat_1.GetChildren()) { - auto dot_identifier_value_1 = transformer.Transform(dot_identifier_item_1.get()); - dot_identifier.push_back(dot_identifier_value_1); + vector dot_identifier_value; + auto &dot_identifier_value_repeat_1 = dot_identifier_opt.GetResult().Cast(); + for (auto &dot_identifier_value_item_1 : dot_identifier_value_repeat_1.GetChildren()) { + auto dot_identifier_value_value_1 = transformer.Transform(dot_identifier_value_item_1.get()); + dot_identifier_value.push_back(dot_identifier_value_value_1); } + dot_identifier = dot_identifier_value; } auto result = TransformUpdateSetColumnTarget(transformer, column_name, dot_identifier); return make_uniq>(result); @@ -5131,11 +6975,13 @@ PEGTransformerFactory::TransformUseTargetCatalogSchemaInternal(PEGTransformer &t vector dot_identifier {}; auto &dot_identifier_opt = list_pr.GetChild(3).Cast(); if (dot_identifier_opt.HasResult()) { - auto &dot_identifier_repeat_1 = dot_identifier_opt.GetResult().Cast(); - for (auto &dot_identifier_item_1 : dot_identifier_repeat_1.GetChildren()) { - auto dot_identifier_value_1 = transformer.Transform(dot_identifier_item_1.get()); - dot_identifier.push_back(dot_identifier_value_1); + vector dot_identifier_value; + auto &dot_identifier_value_repeat_1 = dot_identifier_opt.GetResult().Cast(); + for (auto &dot_identifier_value_item_1 : dot_identifier_value_repeat_1.GetChildren()) { + auto dot_identifier_value_value_1 = transformer.Transform(dot_identifier_value_item_1.get()); + dot_identifier_value.push_back(dot_identifier_value_value_1); } + dot_identifier = dot_identifier_value; } auto result = TransformUseTargetCatalogSchema(transformer, catalog_name, reserved_schema_name, dot_identifier); return make_uniq>(result); @@ -5155,12 +7001,14 @@ unique_ptr PEGTransformerFactory::TransformVacuumStatement VacuumOptions vacuum_options {}; auto &vacuum_options_opt = list_pr.GetChild(1).Cast(); if (vacuum_options_opt.HasResult()) { - vacuum_options = transformer.Transform(vacuum_options_opt.GetResult()); + auto vacuum_options_value = transformer.Transform(vacuum_options_opt.GetResult()); + vacuum_options = vacuum_options_value; } AnalyzeTarget analyze_target {}; auto &analyze_target_opt = list_pr.GetChild(2).Cast(); if (analyze_target_opt.HasResult()) { - analyze_target = transformer.Transform(analyze_target_opt.GetResult()); + auto analyze_target_value = transformer.Transform(analyze_target_opt.GetResult()); + analyze_target = std::move(analyze_target_value); } auto result = TransformVacuumStatement(transformer, vacuum_options, std::move(analyze_target)); return make_uniq>>(std::move(result)); @@ -5193,22 +7041,26 @@ PEGTransformerFactory::TransformVacuumLegacyOptionsInternal(PEGTransformer &tran string opt_full {}; auto &opt_full_opt = list_pr.GetChild(0).Cast(); if (opt_full_opt.HasResult()) { - opt_full = transformer.Transform(opt_full_opt.GetResult()); + auto opt_full_value = transformer.Transform(opt_full_opt.GetResult()); + opt_full = opt_full_value; } string opt_freeze {}; auto &opt_freeze_opt = list_pr.GetChild(1).Cast(); if (opt_freeze_opt.HasResult()) { - opt_freeze = transformer.Transform(opt_freeze_opt.GetResult()); + auto opt_freeze_value = transformer.Transform(opt_freeze_opt.GetResult()); + opt_freeze = opt_freeze_value; } string opt_verbose {}; auto &opt_verbose_opt = list_pr.GetChild(2).Cast(); if (opt_verbose_opt.HasResult()) { - opt_verbose = transformer.Transform(opt_verbose_opt.GetResult()); + auto opt_verbose_value = transformer.Transform(opt_verbose_opt.GetResult()); + opt_verbose = opt_verbose_value; } string opt_analyze {}; auto &opt_analyze_opt = list_pr.GetChild(3).Cast(); if (opt_analyze_opt.HasResult()) { - opt_analyze = transformer.Transform(opt_analyze_opt.GetResult()); + auto opt_analyze_value = transformer.Transform(opt_analyze_opt.GetResult()); + opt_analyze = opt_analyze_value; } auto result = TransformVacuumLegacyOptions(transformer, opt_full, opt_freeze, opt_verbose, opt_analyze); return make_uniq>(result); @@ -5745,6 +7597,156 @@ void PEGTransformerFactory::RegisterGenerated() { {"PragmaParameters", &PEGTransformerFactory::TransformPragmaParametersInternal}, {"PrepareStatement", &PEGTransformerFactory::TransformPrepareStatementInternal}, {"TypeList", &PEGTransformerFactory::TransformTypeListInternal}, + {"SelectStatement", &PEGTransformerFactory::TransformSelectStatementInternal}, + {"SelectSetOpChain", &PEGTransformerFactory::TransformSelectSetOpChainInternal}, + {"SelectSetOpChainTail", &PEGTransformerFactory::TransformSelectSetOpChainTailInternal}, + {"IntersectChain", &PEGTransformerFactory::TransformIntersectChainInternal}, + {"IntersectChainTail", &PEGTransformerFactory::TransformIntersectChainTailInternal}, + {"SetIntersectClause", &PEGTransformerFactory::TransformSetIntersectClauseInternal}, + {"SelectAtom", &PEGTransformerFactory::TransformSelectAtomInternal}, + {"SelectParens", &PEGTransformerFactory::TransformSelectParensInternal}, + {"SetopClause", &PEGTransformerFactory::TransformSetopClauseInternal}, + {"SetopType", &PEGTransformerFactory::TransformSetopTypeInternal}, + {"SetopUnion", &PEGTransformerFactory::TransformSetopUnionInternal}, + {"SetopExcept", &PEGTransformerFactory::TransformSetopExceptInternal}, + {"SelectStatementType", &PEGTransformerFactory::TransformSelectStatementTypeInternal}, + {"ResultModifiers", &PEGTransformerFactory::TransformResultModifiersInternal}, + {"LimitOffset", &PEGTransformerFactory::TransformLimitOffsetInternal}, + {"LimitOffsetClause", &PEGTransformerFactory::TransformLimitOffsetClauseInternal}, + {"OffsetLimitClause", &PEGTransformerFactory::TransformOffsetLimitClauseInternal}, + {"TableStatement", &PEGTransformerFactory::TransformTableStatementInternal}, + {"OptionalParensSimpleSelect", &PEGTransformerFactory::TransformOptionalParensSimpleSelectInternal}, + {"SimpleSelectParens", &PEGTransformerFactory::TransformSimpleSelectParensInternal}, + {"SelectFrom", &PEGTransformerFactory::TransformSelectFromInternal}, + {"SelectFromClause", &PEGTransformerFactory::TransformSelectFromClauseInternal}, + {"FromSelectClause", &PEGTransformerFactory::TransformFromSelectClauseInternal}, + {"WithStatement", &PEGTransformerFactory::TransformWithStatementInternal}, + {"CTEBody", &PEGTransformerFactory::TransformCTEBodyInternal}, + {"CTESelectBody", &PEGTransformerFactory::TransformCTESelectBodyInternal}, + {"CTEDMLBody", &PEGTransformerFactory::TransformCTEDMLBodyInternal}, + {"UsingKey", &PEGTransformerFactory::TransformUsingKeyInternal}, + {"Materialized", &PEGTransformerFactory::TransformMaterializedInternal}, + {"SelectClause", &PEGTransformerFactory::TransformSelectClauseInternal}, + {"TargetList", &PEGTransformerFactory::TransformTargetListInternal}, + {"ColumnAliases", &PEGTransformerFactory::TransformColumnAliasesInternal}, + {"DistinctClause", &PEGTransformerFactory::TransformDistinctClauseInternal}, + {"DistinctAll", &PEGTransformerFactory::TransformDistinctAllInternal}, + {"DistinctOn", &PEGTransformerFactory::TransformDistinctOnInternal}, + {"DistinctOnTargets", &PEGTransformerFactory::TransformDistinctOnTargetsInternal}, + {"InnerTableRef", &PEGTransformerFactory::TransformInnerTableRefInternal}, + {"TableSubquery", &PEGTransformerFactory::TransformTableSubqueryInternal}, + {"BaseTableRef", &PEGTransformerFactory::TransformBaseTableRefInternal}, + {"TableAliasColon", &PEGTransformerFactory::TransformTableAliasColonInternal}, + {"ValuesRef", &PEGTransformerFactory::TransformValuesRefInternal}, + {"ParensTableRef", &PEGTransformerFactory::TransformParensTableRefInternal}, + {"JoinOrPivot", &PEGTransformerFactory::TransformJoinOrPivotInternal}, + {"TablePivotClause", &PEGTransformerFactory::TransformTablePivotClauseInternal}, + {"TablePivotClauseBody", &PEGTransformerFactory::TransformTablePivotClauseBodyInternal}, + {"PivotGroupByList", &PEGTransformerFactory::TransformPivotGroupByListInternal}, + {"TableUnpivotClause", &PEGTransformerFactory::TransformTableUnpivotClauseInternal}, + {"TableUnpivotClauseBody", &PEGTransformerFactory::TransformTableUnpivotClauseBodyInternal}, + {"PivotHeader", &PEGTransformerFactory::TransformPivotHeaderInternal}, + {"PivotValueList", &PEGTransformerFactory::TransformPivotValueListInternal}, + {"PivotValueTarget", &PEGTransformerFactory::TransformPivotValueTargetInternal}, + {"UnpivotValueList", &PEGTransformerFactory::TransformUnpivotValueListInternal}, + {"PivotTargetList", &PEGTransformerFactory::TransformPivotTargetListInternal}, + {"UnpivotTargetList", &PEGTransformerFactory::TransformUnpivotTargetListInternal}, + {"Lateral", &PEGTransformerFactory::TransformLateralInternal}, + {"BaseTableName", &PEGTransformerFactory::TransformBaseTableNameInternal}, + {"UnqualifiedBaseTableName", &PEGTransformerFactory::TransformUnqualifiedBaseTableNameInternal}, + {"SchemaReservedTable", &PEGTransformerFactory::TransformSchemaReservedTableInternal}, + {"CatalogReservedSchemaTable", &PEGTransformerFactory::TransformCatalogReservedSchemaTableInternal}, + {"TableFunction", &PEGTransformerFactory::TransformTableFunctionInternal}, + {"TableFunctionLateralOpt", &PEGTransformerFactory::TransformTableFunctionLateralOptInternal}, + {"TableFunctionAliasColon", &PEGTransformerFactory::TransformTableFunctionAliasColonInternal}, + {"WithOrdinality", &PEGTransformerFactory::TransformWithOrdinalityInternal}, + {"QualifiedTableFunction", &PEGTransformerFactory::TransformQualifiedTableFunctionInternal}, + {"TableFunctionArguments", &PEGTransformerFactory::TransformTableFunctionArgumentsInternal}, + {"FunctionArgument", &PEGTransformerFactory::TransformFunctionArgumentInternal}, + {"NamedFunctionArgument", &PEGTransformerFactory::TransformNamedFunctionArgumentInternal}, + {"PositionalFunctionArgument", &PEGTransformerFactory::TransformPositionalFunctionArgumentInternal}, + {"NamedParameter", &PEGTransformerFactory::TransformNamedParameterInternal}, + {"TableAlias", &PEGTransformerFactory::TransformTableAliasInternal}, + {"TableAliasAs", &PEGTransformerFactory::TransformTableAliasAsInternal}, + {"TableAliasWithoutAs", &PEGTransformerFactory::TransformTableAliasWithoutAsInternal}, + {"AtClause", &PEGTransformerFactory::TransformAtClauseInternal}, + {"AtSpecifier", &PEGTransformerFactory::TransformAtSpecifierInternal}, + {"AtUnit", &PEGTransformerFactory::TransformAtUnitInternal}, + {"VersionAtUnit", &PEGTransformerFactory::TransformVersionAtUnitInternal}, + {"TimestampAtUnit", &PEGTransformerFactory::TransformTimestampAtUnitInternal}, + {"JoinClause", &PEGTransformerFactory::TransformJoinClauseInternal}, + {"RegularJoinClause", &PEGTransformerFactory::TransformRegularJoinClauseInternal}, + {"Asof", &PEGTransformerFactory::TransformAsofInternal}, + {"JoinWithoutOnClause", &PEGTransformerFactory::TransformJoinWithoutOnClauseInternal}, + {"JoinQualifier", &PEGTransformerFactory::TransformJoinQualifierInternal}, + {"OnClause", &PEGTransformerFactory::TransformOnClauseInternal}, + {"UsingClause", &PEGTransformerFactory::TransformUsingClauseInternal}, + {"JoinType", &PEGTransformerFactory::TransformJoinTypeInternal}, + {"JoinPrefix", &PEGTransformerFactory::TransformJoinPrefixInternal}, + {"CrossJoinPrefix", &PEGTransformerFactory::TransformCrossJoinPrefixInternal}, + {"NaturalJoinPrefix", &PEGTransformerFactory::TransformNaturalJoinPrefixInternal}, + {"PositionalJoinPrefix", &PEGTransformerFactory::TransformPositionalJoinPrefixInternal}, + {"FullJoin", &PEGTransformerFactory::TransformFullJoinInternal}, + {"LeftJoin", &PEGTransformerFactory::TransformLeftJoinInternal}, + {"RightJoin", &PEGTransformerFactory::TransformRightJoinInternal}, + {"SemiJoin", &PEGTransformerFactory::TransformSemiJoinInternal}, + {"AntiJoin", &PEGTransformerFactory::TransformAntiJoinInternal}, + {"InnerJoin", &PEGTransformerFactory::TransformInnerJoinInternal}, + {"FromClause", &PEGTransformerFactory::TransformFromClauseInternal}, + {"WhereClause", &PEGTransformerFactory::TransformWhereClauseInternal}, + {"GroupByClause", &PEGTransformerFactory::TransformGroupByClauseInternal}, + {"HavingClause", &PEGTransformerFactory::TransformHavingClauseInternal}, + {"QualifyClause", &PEGTransformerFactory::TransformQualifyClauseInternal}, + {"SampleClause", &PEGTransformerFactory::TransformSampleClauseInternal}, + {"WindowClause", &PEGTransformerFactory::TransformWindowClauseInternal}, + {"SampleEntry", &PEGTransformerFactory::TransformSampleEntryInternal}, + {"SampleEntryCount", &PEGTransformerFactory::TransformSampleEntryCountInternal}, + {"SampleEntryFunction", &PEGTransformerFactory::TransformSampleEntryFunctionInternal}, + {"SampleFunction", &PEGTransformerFactory::TransformSampleFunctionInternal}, + {"SampleProperties", &PEGTransformerFactory::TransformSamplePropertiesInternal}, + {"RepeatableSample", &PEGTransformerFactory::TransformRepeatableSampleInternal}, + {"SampleSeed", &PEGTransformerFactory::TransformSampleSeedInternal}, + {"SampleCount", &PEGTransformerFactory::TransformSampleCountInternal}, + {"SampleValue", &PEGTransformerFactory::TransformSampleValueInternal}, + {"SampleUnit", &PEGTransformerFactory::TransformSampleUnitInternal}, + {"SamplePercentage", &PEGTransformerFactory::TransformSamplePercentageInternal}, + {"SampleRows", &PEGTransformerFactory::TransformSampleRowsInternal}, + {"GroupByExpressions", &PEGTransformerFactory::TransformGroupByExpressionsInternal}, + {"GroupByAll", &PEGTransformerFactory::TransformGroupByAllInternal}, + {"GroupByList", &PEGTransformerFactory::TransformGroupByListInternal}, + {"GroupByExpression", &PEGTransformerFactory::TransformGroupByExpressionInternal}, + {"GroupByBaseExpression", &PEGTransformerFactory::TransformGroupByBaseExpressionInternal}, + {"EmptyGroupingItem", &PEGTransformerFactory::TransformEmptyGroupingItemInternal}, + {"CubeOrRollupClause", &PEGTransformerFactory::TransformCubeOrRollupClauseInternal}, + {"CubeOrRollup", &PEGTransformerFactory::TransformCubeOrRollupInternal}, + {"CubeKeyword", &PEGTransformerFactory::TransformCubeKeywordInternal}, + {"RollupKeyword", &PEGTransformerFactory::TransformRollupKeywordInternal}, + {"GroupingSetsClause", &PEGTransformerFactory::TransformGroupingSetsClauseInternal}, + {"SubqueryReference", &PEGTransformerFactory::TransformSubqueryReferenceInternal}, + {"OrderByExpression", &PEGTransformerFactory::TransformOrderByExpressionInternal}, + {"DescOrAsc", &PEGTransformerFactory::TransformDescOrAscInternal}, + {"DescendingOrder", &PEGTransformerFactory::TransformDescendingOrderInternal}, + {"AscendingOrder", &PEGTransformerFactory::TransformAscendingOrderInternal}, + {"NullsFirstOrLast", &PEGTransformerFactory::TransformNullsFirstOrLastInternal}, + {"NullsFirst", &PEGTransformerFactory::TransformNullsFirstInternal}, + {"NullsLast", &PEGTransformerFactory::TransformNullsLastInternal}, + {"OrderByClause", &PEGTransformerFactory::TransformOrderByClauseInternal}, + {"OrderByExpressions", &PEGTransformerFactory::TransformOrderByExpressionsInternal}, + {"OrderByExpressionList", &PEGTransformerFactory::TransformOrderByExpressionListInternal}, + {"OrderByAll", &PEGTransformerFactory::TransformOrderByAllInternal}, + {"LimitClause", &PEGTransformerFactory::TransformLimitClauseInternal}, + {"OffsetClause", &PEGTransformerFactory::TransformOffsetClauseInternal}, + {"OffsetValue", &PEGTransformerFactory::TransformOffsetValueInternal}, + {"LimitValue", &PEGTransformerFactory::TransformLimitValueInternal}, + {"LimitAll", &PEGTransformerFactory::TransformLimitAllInternal}, + {"LimitLiteralPercent", &PEGTransformerFactory::TransformLimitLiteralPercentInternal}, + {"LimitExpression", &PEGTransformerFactory::TransformLimitExpressionInternal}, + {"AliasedExpression", &PEGTransformerFactory::TransformAliasedExpressionInternal}, + {"ColIdExpression", &PEGTransformerFactory::TransformColIdExpressionInternal}, + {"ExpressionAsCollabel", &PEGTransformerFactory::TransformExpressionAsCollabelInternal}, + {"ExpressionOptIdentifier", &PEGTransformerFactory::TransformExpressionOptIdentifierInternal}, + {"ValuesClause", &PEGTransformerFactory::TransformValuesClauseInternal}, + {"ValuesExpressions", &PEGTransformerFactory::TransformValuesExpressionsInternal}, {"SetStatement", &PEGTransformerFactory::TransformSetStatementInternal}, {"SetAssignmentOrTimeZone", &PEGTransformerFactory::TransformSetAssignmentOrTimeZoneInternal}, {"ResetStatement", &PEGTransformerFactory::TransformResetStatementInternal}, diff --git a/src/duckdb/src/parser/peg/transformer/transform_select.cpp b/src/duckdb/src/parser/peg/transformer/transform_select.cpp index 2fe6a9848..bf0751c66 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_select.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_select.cpp @@ -23,14 +23,14 @@ namespace duckdb { -unique_ptr PEGTransformerFactory::TransformSelectStatement(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0)); +unique_ptr +PEGTransformerFactory::TransformSelectStatement(PEGTransformer &transformer, + unique_ptr select_statement_internal) { + return std::move(select_statement_internal); } -unique_ptr PEGTransformerFactory::TransformSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { +unique_ptr PEGTransformerFactory::TransformSelectStatementInternalRule(PEGTransformer &transformer, + ParseResult &parse_result) { auto &list_pr = parse_result.Cast(); CommonTableExpressionMap cte_map; transformer.TransformOptional(list_pr, 0, cte_map); @@ -66,19 +66,16 @@ unique_ptr PEGTransformerFactory::TransformSelectStatementInter return select_statement; } -unique_ptr PEGTransformerFactory::TransformSelectSetOpChain(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select = transformer.Transform>(list_pr.Child(0)); - auto &setop_opt = list_pr.Child(1); - if (!setop_opt.HasResult()) { +unique_ptr PEGTransformerFactory::TransformSelectSetOpChain( + PEGTransformer &transformer, unique_ptr intersect_chain, + optional, unique_ptr>>> select_set_op_chain_tail) { + auto select = std::move(intersect_chain); + if (!select_set_op_chain_tail) { return select; } - auto &setop_repeat = setop_opt.GetResult().Cast(); - for (auto setop : setop_repeat.GetChildren()) { - auto &setop_list = setop.get().Cast(); - auto setop_result = transformer.Transform>(setop_list.Child(0)); - auto right_select = transformer.Transform>(setop_list.Child(1)); + for (auto &tail : *select_set_op_chain_tail) { + auto setop_result = std::move(tail.first); + auto right_select = std::move(tail.second); if (select->node->type == QueryNodeType::SET_OPERATION_NODE && select->node->modifiers.empty() && select->node->cte_map.map.empty()) { auto &existing = select->node->Cast(); @@ -96,19 +93,23 @@ unique_ptr PEGTransformerFactory::TransformSelectSetOpChain(PEG return select; } -unique_ptr PEGTransformerFactory::TransformIntersectChain(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select = transformer.Transform>(list_pr.GetChild(0)); - auto &intersect_opt = list_pr.Child(1); - if (!intersect_opt.HasResult()) { +pair, unique_ptr> +PEGTransformerFactory::TransformSelectSetOpChainTail(PEGTransformer &transformer, + unique_ptr setop_clause, + unique_ptr intersect_chain) { + return make_pair(std::move(setop_clause), std::move(intersect_chain)); +} + +unique_ptr PEGTransformerFactory::TransformIntersectChain( + PEGTransformer &transformer, unique_ptr select_atom, + optional, unique_ptr>>> intersect_chain_tail) { + auto select = std::move(select_atom); + if (!intersect_chain_tail) { return select; } - auto &intersect_repeat = intersect_opt.GetResult().Cast(); - for (auto &intersect : intersect_repeat.GetChildren()) { - auto &intersect_list = intersect.get().Cast(); - auto intersect_node = transformer.Transform>(intersect_list.GetChild(0)); - auto right_select = transformer.Transform>(intersect_list.GetChild(1)); + for (auto &tail : *intersect_chain_tail) { + auto intersect_node = std::move(tail.first); + auto right_select = std::move(tail.second); intersect_node->children.push_back(std::move(select->node)); intersect_node->children.push_back(std::move(right_select->node)); select->node = std::move(intersect_node); @@ -116,35 +117,33 @@ unique_ptr PEGTransformerFactory::TransformIntersectChain(PEGTr return select; } +pair, unique_ptr> +PEGTransformerFactory::TransformIntersectChainTail(PEGTransformer &transformer, + unique_ptr set_intersect_clause, + unique_ptr select_atom) { + return make_pair(std::move(set_intersect_clause), std::move(select_atom)); +} + unique_ptr PEGTransformerFactory::TransformSetIntersectClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); + const optional &distinct_or_all) { auto result = make_uniq(); result->setop_type = SetOperationType::INTERSECT; - auto &is_distinct_opt = list_pr.Child(1); - if (is_distinct_opt.HasResult()) { - result->setop_all = !transformer.Transform(is_distinct_opt.GetResult()); + if (distinct_or_all) { + result->setop_all = !*distinct_or_all; } return result; } -unique_ptr PEGTransformerFactory::TransformSelectAtom(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - unique_ptr PEGTransformerFactory::TransformSetopClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); + const SetOperationType &setop_type, + const optional &distinct_or_all, + const bool &has_result) { auto result = make_uniq(); - result->setop_type = transformer.Transform(list_pr.Child(0)); - auto &is_distinct_opt = list_pr.Child(1); - if (is_distinct_opt.HasResult()) { - result->setop_all = !transformer.Transform(is_distinct_opt.GetResult()); + result->setop_type = setop_type; + if (distinct_or_all) { + result->setop_all = !*distinct_or_all; } - auto &by_name = list_pr.Child(2); - if (by_name.HasResult()) { + if (has_result) { if (result->setop_type == SetOperationType::UNION) { result->setop_type = SetOperationType::UNION_BY_NAME; } else { @@ -154,41 +153,34 @@ unique_ptr PEGTransformerFactory::TransformSetopClause(PEGTran return result; } -bool PEGTransformerFactory::TransformDistinctOrAll(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0).GetResult(); - return StringUtil::CIEquals(choice_pr.Cast().keyword, "distinct"); +SetOperationType PEGTransformerFactory::TransformSetopUnion(PEGTransformer &transformer) { + return SetOperationType::UNION; } -SetOperationType PEGTransformerFactory::TransformSetopType(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.TransformEnum(list_pr.Child(0).GetResult()); +SetOperationType PEGTransformerFactory::TransformSetopExcept(PEGTransformer &transformer) { + return SetOperationType::EXCEPT; } -unique_ptr PEGTransformerFactory::TransformSelectParens(PEGTransformer &transformer, - ParseResult &parse_result) { +bool PEGTransformerFactory::TransformDistinctOrAll(PEGTransformer &transformer, ParseResult &parse_result) { auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(0)); - return transformer.Transform>(extract_parens); + auto &choice_pr = list_pr.Child(0); + return transformer.Transform(choice_pr.GetResult()); } -unique_ptr PEGTransformerFactory::TransformSelectStatementType(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); +bool PEGTransformerFactory::TransformDistinctKeyword(PEGTransformer &transformer, ParseResult &parse_result) { + return true; } -unique_ptr PEGTransformerFactory::TransformOptionalParensSimpleSelect(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); +bool PEGTransformerFactory::TransformAllKeyword(PEGTransformer &transformer, ParseResult &parse_result) { + return false; } -unique_ptr PEGTransformerFactory::TransformSimpleSelectParens(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(0)); - return transformer.Transform>(extract_parens); +bool PEGTransformerFactory::TransformLateral(PEGTransformer &transformer) { + return true; +} + +bool PEGTransformerFactory::TransformWithOrdinality(PEGTransformer &transformer) { + return true; } unique_ptr PEGTransformerFactory::TransformSimpleSelect(PEGTransformer &transformer, @@ -200,14 +192,14 @@ unique_ptr PEGTransformerFactory::TransformSimpleSelect(PEGTran transformer.Transform>>(opt_window_clause.GetResult()); for (auto &window_func : window_functions) { D_ASSERT(!window_func->GetAlias().empty()); - string window_name(window_func->GetAlias()); + auto window_name = window_func->GetAlias(); window_func->ClearAlias(); - auto it = transformer.window_clauses.find(Identifier(window_name)); + auto it = transformer.window_clauses.find(window_name); if (it != transformer.window_clauses.end()) { - throw ParserException("window \"%s\" is already defined", window_name); + throw ParserException("window \"%s\" is already defined", window_name.GetIdentifierName()); } auto window_function = unique_ptr_cast(std::move(window_func)); - transformer.window_clauses[Identifier(window_name)] = std::move(window_function); + transformer.window_clauses[window_name] = std::move(window_function); } } auto select_node = transformer.Transform>(list_pr.Child(0)); @@ -231,187 +223,34 @@ unique_ptr PEGTransformerFactory::TransformSimpleSelect(PEGTran return select_statement; } -unique_ptr PEGTransformerFactory::TransformSelectFrom(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformSelectFromClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_node = transformer.Transform>(list_pr.Child(0)); - auto &opt_from = list_pr.Child(1); - if (opt_from.HasResult()) { - select_node->from_table = transformer.Transform>(opt_from.GetResult()); - } else { - select_node->from_table = make_uniq(); - } - return select_node; -} - -unique_ptr PEGTransformerFactory::TransformFromSelectClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_node = make_uniq(); - auto from_table = transformer.Transform>(list_pr.Child(0)); - auto &opt_select = list_pr.Child(1); - if (opt_select.HasResult()) { - select_node = transformer.Transform>(opt_select.GetResult()); - } else { - select_node->select_list.push_back(make_uniq()); - } - select_node->from_table = std::move(from_table); - return select_node; -} - -unique_ptr PEGTransformerFactory::TransformFromClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_ref_list = ExtractParseResultsFromList(list_pr.Child(1)); - auto result_table_ref = transformer.Transform>(table_ref_list[0]); - if (table_ref_list.size() == 1) { - return result_table_ref; - } - for (idx_t i = 1; i < table_ref_list.size(); i++) { - auto table_ref = transformer.Transform>(table_ref_list[i]); - auto cross_product = make_uniq(); - cross_product->left = std::move(result_table_ref); - cross_product->right = std::move(table_ref); - cross_product->ref_type = JoinRefType::CROSS; - cross_product->is_implicit = true; - result_table_ref = std::move(cross_product); - } - return result_table_ref; -} - -unique_ptr PEGTransformerFactory::TransformSelectClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto result = make_uniq(); - auto &opt_distinct = list_pr.Child(1); - if (opt_distinct.HasResult()) { - auto distinct_clause = transformer.Transform(opt_distinct.GetResult()); - if (distinct_clause.is_distinct) { - auto distinct_modifier = make_uniq(); - for (auto &distinct_on : distinct_clause.distinct_targets) { - distinct_modifier->distinct_on_targets.push_back(distinct_on->Copy()); - } - result->modifiers.push_back(std::move(distinct_modifier)); - } - } - auto &opt_target_list = list_pr.Child(2); - if (!opt_target_list.HasResult()) { - throw ParserException("SELECT clause without selection list"); - } - auto target_list = transformer.Transform>>(opt_target_list.GetResult()); - for (auto &expr_ptr : target_list) { - result->select_list.push_back(std::move(expr_ptr)); - } - return result; -} - -DistinctClause PEGTransformerFactory::TransformDistinctClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0).GetResult()); -} - -DistinctClause PEGTransformerFactory::TransformDistinctOn(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - DistinctClause result; - result.is_distinct = true; - transformer.TransformOptional>>(list_pr, 1, result.distinct_targets); - return result; -} - -DistinctClause PEGTransformerFactory::TransformDistinctAll(PEGTransformer &transformer, ParseResult &parse_result) { - DistinctClause result; - result.is_distinct = false; - return result; -} - -vector> PEGTransformerFactory::TransformDistinctOnTargets(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> result; - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - auto expr_list = ExtractParseResultsFromList(extract_parens); - for (auto &expr : expr_list) { - result.push_back(transformer.Transform>(expr)); - } - return result; +FunctionArgument PEGTransformerFactory::TransformNamedFunctionArgument(PEGTransformer &transformer, + MacroParameter named_parameter) { + named_parameter.expression->SetAlias(named_parameter.name); + return FunctionArgument(named_parameter.name, std::move(named_parameter.expression)); } -FunctionArgument PEGTransformerFactory::TransformFunctionArgument(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0).GetResult(); - if (choice_pr.name == "NamedParameter") { - auto parameter = transformer.Transform(choice_pr); - parameter.expression->SetAlias(parameter.name); - return FunctionArgument(parameter.name, std::move(parameter.expression)); - } - - return FunctionArgument(transformer.Transform>(choice_pr)); +FunctionArgument PEGTransformerFactory::TransformPositionalFunctionArgument(PEGTransformer &transformer, + unique_ptr expression) { + return FunctionArgument(std::move(expression)); } -MacroParameter PEGTransformerFactory::TransformNamedParameter(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); +MacroParameter PEGTransformerFactory::TransformNamedParameter(PEGTransformer &transformer, + const Identifier &type_func_name, + const optional &type, + unique_ptr expression) { MacroParameter parameter; - parameter.expression = transformer.Transform>(list_pr.Child(3)); - parameter.name = Identifier(transformer.Transform(list_pr.Child(0))); + parameter.expression = std::move(expression); + parameter.name = type_func_name; parameter.is_default = true; - transformer.TransformOptional(list_pr, 1, parameter.type); - return parameter; -} - -vector PEGTransformerFactory::TransformTableFunctionArguments(PEGTransformer &transformer, - ParseResult &parse_result) { - // TableFunctionArguments <- Parens(List(FunctionArgument)?) - vector result; - auto &list_pr = parse_result.Cast(); - auto &stripped_parens = ExtractResultFromParens(list_pr.Child(0)).Cast(); - if (stripped_parens.HasResult()) { - auto argument_list = ExtractParseResultsFromList(stripped_parens.GetResult()); - for (auto &argument : argument_list) { - result.push_back(transformer.Transform(argument)); - } + if (type) { + parameter.type = *type; } - - return result; -} - -unique_ptr PEGTransformerFactory::TransformBaseTableName(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - auto table_name = choice_pr.GetResult().Cast().identifier; - const auto description = TableDescription(INVALID_CATALOG, INVALID_SCHEMA, table_name); - return make_uniq(description); - } - return transformer.Transform>(choice_pr.GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformSchemaReservedTable(PEGTransformer &transformer, - ParseResult &parse_result) { - // SchemaReservedTable <- SchemaQualification ReservedTableName - auto &list_pr = parse_result.Cast(); - auto schema = transformer.Transform(list_pr.Child(0)); - auto table_name = list_pr.Child(1).identifier; - - const auto description = TableDescription(INVALID_CATALOG, schema, table_name); - return make_uniq(description); + return parameter; } -unique_ptr PEGTransformerFactory::TransformCatalogReservedSchemaTable(PEGTransformer &transformer, - ParseResult &parse_result) { - // CatalogReservedSchemaTable <- CatalogQualification ReservedSchemaQualification ReservedTableName - auto &list_pr = parse_result.Cast(); - auto catalog = transformer.Transform(list_pr.Child(0)); - auto schema = transformer.Transform(list_pr.Child(1)); - auto table_name = list_pr.Child(2).identifier; - const auto description = TableDescription(catalog, schema, table_name); +unique_ptr PEGTransformerFactory::TransformUnqualifiedBaseTableName(PEGTransformer &transformer, + const Identifier &table_name) { + const auto description = TableDescription(INVALID_CATALOG, INVALID_SCHEMA, table_name); return make_uniq(description); } @@ -425,24 +264,13 @@ Identifier PEGTransformerFactory::TransformCatalogQualification(PEGTransformer & return catalog_name; } -QualifiedName -PEGTransformerFactory::TransformCatalogReservedSchemaIdentifierOrStringLiteral(PEGTransformer &transformer, - optional_ptr parse_result) { - QualifiedName result; - auto &list_pr = parse_result->Cast(); - result.catalog = transformer.Transform(list_pr.Child(0)); - result.schema = transformer.Transform(list_pr.Child(1)); - result.name = transformer.Transform(list_pr.Child(2)); - return result; -} - QualifiedName PEGTransformerFactory::TransformCatalogReservedSchemaIdentifier( PEGTransformer &transformer, const Identifier &catalog_qualification, const Identifier &reserved_schema_qualification, const Identifier &reserved_identifier_or_string_literal) { QualifiedName result; result.catalog = catalog_qualification; result.schema = reserved_schema_qualification; - result.name = Identifier(reserved_identifier_or_string_literal); + result.name = reserved_identifier_or_string_literal; return result; } @@ -452,102 +280,7 @@ QualifiedName PEGTransformerFactory::TransformSchemaReservedIdentifierOrStringLi QualifiedName result; result.catalog = INVALID_CATALOG; result.schema = schema_qualification; - result.name = Identifier(reserved_identifier_or_string_literal); - return result; -} - -QualifiedName PEGTransformerFactory::TransformTableNameIdentifierOrStringLiteral(PEGTransformer &transformer, - ParseResult &parse_result) { - QualifiedName result; - auto &list_pr = parse_result.Cast(); - result.catalog = INVALID_CATALOG; - result.schema = INVALID_SCHEMA; - result.name = transformer.Transform(list_pr.Child(0)); - return result; -} - -unique_ptr PEGTransformerFactory::TransformWhereClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(1)); -} - -vector> PEGTransformerFactory::TransformTargetList(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = ExtractParseResultsFromList(list_pr.Child(0)); - vector> result; - for (auto target : target_list) { - result.push_back(transformer.Transform>(target)); - } - return result; -} - -unique_ptr PEGTransformerFactory::TransformAliasedExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformExpressionAsCollabel(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expr = transformer.Transform>(list_pr.Child(0)); - auto &collabel_or_string = list_pr.Child(2); - expr->SetAlias(transformer.Transform(collabel_or_string)); - return expr; -} - -unique_ptr PEGTransformerFactory::TransformColIdExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &colid = list_pr.Child(0); - auto expr = transformer.Transform>(list_pr.Child(2)); - expr->SetAlias(transformer.Transform(colid)); - return expr; -} - -unique_ptr PEGTransformerFactory::TransformExpressionOptIdentifier(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expr = transformer.Transform>(list_pr.Child(0)); - auto &opt_identifier = list_pr.Child(1); - if (opt_identifier.HasResult()) { - expr->SetAlias(opt_identifier.GetResult().Cast().identifier); - } - return expr; -} - -TableAlias PEGTransformerFactory::TransformTableAlias(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0).GetResult()); -} - -TableAlias PEGTransformerFactory::TransformTableAliasAs(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - TableAlias result; - auto qualified_name = transformer.Transform(list_pr.Child(1)); - result.name = qualified_name.name; - transformer.TransformOptional>(list_pr, 2, result.column_name_alias); - return result; -} - -TableAlias PEGTransformerFactory::TransformTableAliasWithoutAs(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - TableAlias result; - result.name = list_pr.Child(0).identifier; - transformer.TransformOptional>(list_pr, 1, result.column_name_alias); - return result; -} - -vector PEGTransformerFactory::TransformColumnAliases(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector result; - auto &extract_parens = ExtractResultFromParens(list_pr.Child(0)); - auto alias_list = ExtractParseResultsFromList(extract_parens); - for (auto alias : alias_list) { - result.push_back(transformer.Transform(alias)); - } + result.name = reserved_identifier_or_string_literal; return result; } @@ -626,43 +359,29 @@ unique_ptr PEGTransformerFactory::TransformTableRef(PEGTransformer &tr return inner_table_ref; } -unique_ptr PEGTransformerFactory::TransformJoinOrPivot(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformTableUnpivotClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); +unique_ptr PEGTransformerFactory::TransformTableUnpivotClauseBody(PEGTransformer &transformer, + const vector &unpivot_header, + vector unpivot_value_list) { auto result = make_uniq(); - transformer.TransformOptional(list_pr, 1, result->include_nulls); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(2)); - auto &inner_list = extract_parens.Cast(); - result->unpivot_names = transformer.Transform>(inner_list.GetChild(0)); - auto &pivot_values_list = inner_list.Child(2); - for (auto pivot_value : pivot_values_list.GetChildren()) { - result->pivots.push_back(transformer.Transform(pivot_value)); - } + result->unpivot_names = StringsToIdentifiers(unpivot_header); + result->pivots = std::move(unpivot_value_list); if (result->pivots.size() > 1) { throw ParserException("UNPIVOT requires a single pivot element"); } - TableAlias pivot_alias; - transformer.TransformOptional(list_pr, 3, pivot_alias); - result->alias = pivot_alias.name; - result->column_name_alias = pivot_alias.column_name_alias; return std::move(result); } -PivotColumn PEGTransformerFactory::TransformUnpivotValueList(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - PivotColumn result; - result.unpivot_names = transformer.Transform>(list_pr.GetChild(0)); - if (result.unpivot_names.size() != 1) { - throw ParserException("UNPIVOT requires a single column name for the PIVOT IN clause"); +unique_ptr PEGTransformerFactory::TransformTableUnpivotClause(PEGTransformer &transformer, + const optional &include_or_exclude_nulls, + unique_ptr table_unpivot_clause_body, + const optional &table_alias) { + auto &result = table_unpivot_clause_body->Cast(); + result.include_nulls = include_or_exclude_nulls.value_or(false); + if (table_alias) { + result.alias = table_alias->name; + result.column_name_alias = table_alias->column_name_alias; } - result.entries = transformer.Transform>(list_pr.GetChild(2)); - return result; + return table_unpivot_clause_body; } void PEGTransformerFactory::GetValueFromExpression(unique_ptr &expr, vector &result) { @@ -730,63 +449,44 @@ static bool PivotEntryIsTuple(const PivotColumnEntry &entry) { return function.FunctionName() == "row"; } -vector PEGTransformerFactory::TransformUnpivotTargetList(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.GetChild(0)); - auto target_list = transformer.Transform>>(extract_parens); - vector result; - for (auto &target : target_list) { - PivotColumnEntry pivot_entry; - pivot_entry.alias = target->GetAlias(); - pivot_entry.expr = std::move(target); - result.push_back(std::move(pivot_entry)); - } - return result; -} - -unique_ptr PEGTransformerFactory::TransformTablePivotClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - auto &inner_list = extract_parens.Cast(); +unique_ptr PEGTransformerFactory::TransformTablePivotClauseBody( + PEGTransformer &transformer, vector> target_list, vector pivot_value_list, + const optional> &pivot_group_by_list) { auto result = make_uniq(); - result->aggregates = - transformer.Transform>>(inner_list.Child(0)); - auto &pivot_values_list = inner_list.Child(2); - for (auto pivot_value : pivot_values_list.GetChildren()) { - result->pivots.push_back(transformer.Transform(pivot_value)); - } - transformer.TransformOptional>(inner_list, 3, result->groups); - TableAlias table_alias; - transformer.TransformOptional(list_pr, 2, table_alias); - result->alias = table_alias.name; - result->column_name_alias = table_alias.column_name_alias; + result->aggregates = std::move(target_list); + result->pivots = std::move(pivot_value_list); + if (pivot_group_by_list) { + result->groups = StringsToIdentifiers(*pivot_group_by_list); + } return std::move(result); } -vector PEGTransformerFactory::TransformPivotGroupByList(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto group_list = ExtractParseResultsFromList(list_pr.GetChild(2)); - vector result; - for (auto &colid : group_list) { - result.push_back(transformer.Transform(colid)); +unique_ptr PEGTransformerFactory::TransformTablePivotClause(PEGTransformer &transformer, + unique_ptr table_pivot_clause_body, + const optional &table_alias) { + auto &result = table_pivot_clause_body->Cast(); + if (table_alias) { + result.alias = table_alias->name; + result.column_name_alias = table_alias->column_name_alias; } - return result; + return table_pivot_clause_body; } -PivotColumn PEGTransformerFactory::TransformPivotValueList(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); +PivotColumn PEGTransformerFactory::TransformPivotValueTarget(PEGTransformer &transformer, ParseResult &choice_result) { PivotColumn result; - auto pivot_expression = transformer.Transform>(list_pr.Child(0)); - auto &inner_list = list_pr.Child(2); - auto &target_list_or_enum = inner_list.Child(0).GetResult(); - if (target_list_or_enum.type == ParseResultType::IDENTIFIER) { - result.pivot_enum = target_list_or_enum.Cast().identifier; + if (choice_result.type == ParseResultType::IDENTIFIER) { + result.pivot_enum = choice_result.Cast().identifier; } else { - result.entries = transformer.Transform>(target_list_or_enum); + result.entries = transformer.Transform>(choice_result); } + return result; +} + +PivotColumn PEGTransformerFactory::TransformPivotValueList(PEGTransformer &transformer, + unique_ptr pivot_header, + PivotColumn pivot_value_target) { + auto result = std::move(pivot_value_target); + auto pivot_expression = std::move(pivot_header); if (pivot_expression->GetExpressionClass() != ExpressionClass::FUNCTION) { result.pivot_expressions.push_back(std::move(pivot_expression)); return result; @@ -816,50 +516,17 @@ PivotColumn PEGTransformerFactory::TransformPivotValueList(PEGTransformer &trans return result; } -unique_ptr PEGTransformerFactory::TransformPivotHeader(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.GetChild(0)); -} - -vector PEGTransformerFactory::TransformPivotTargetList(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector result; - auto &extract_target_list = ExtractResultFromParens(list_pr.GetChild(0)); - auto target_list = transformer.Transform>>(extract_target_list); - for (auto &target : target_list) { - PivotColumnEntry pivot_entry; - pivot_entry.alias = target->GetAlias(); - bool transformed = TransformPivotInList(target, pivot_entry); - if (!transformed) { - // For pivot we throw an exception - pivot_entry.expr = std::move(target); - } - result.push_back(std::move(pivot_entry)); - } - return result; -} - -unique_ptr PEGTransformerFactory::TransformJoinClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - unique_ptr PEGTransformerFactory::TransformRegularJoinClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); + const optional &asof, + const optional &join_type, + unique_ptr table_ref, + JoinQualifier join_qualifier) { auto result = make_uniq(); - auto asof = list_pr.Child(0).HasResult(); - if (asof) { + if (asof.value_or(false)) { result->ref_type = JoinRefType::ASOF; } - auto join_type = JoinType::INNER; - transformer.TransformOptional(list_pr, 1, join_type); - result->type = join_type; - result->right = transformer.Transform>(list_pr.Child(3)); - auto join_qualifier = transformer.Transform(list_pr.Child(4)); + result->type = join_type.value_or(JoinType::INNER); + result->right = std::move(table_ref); if (join_qualifier.on_clause) { result->condition = std::move(join_qualifier.on_clause); } else if (!join_qualifier.using_columns.empty()) { @@ -870,410 +537,91 @@ unique_ptr PEGTransformerFactory::TransformRegularJoinClause(PEGTransf return std::move(result); } -JoinType PEGTransformerFactory::TransformJoinType(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.TransformEnum(list_pr.Child(0).GetResult()); +bool PEGTransformerFactory::TransformAsof(PEGTransformer &transformer) { + return true; } -JoinQualifier PEGTransformerFactory::TransformJoinQualifier(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0).GetResult()); +JoinType PEGTransformerFactory::TransformFullJoin(PEGTransformer &transformer, const bool &has_result) { + return JoinType::OUTER; } -JoinQualifier PEGTransformerFactory::TransformOnClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - JoinQualifier result; - result.on_clause = transformer.Transform>(list_pr.Child(1)); - return result; +JoinType PEGTransformerFactory::TransformLeftJoin(PEGTransformer &transformer, const bool &has_result) { + return JoinType::LEFT; } -JoinQualifier PEGTransformerFactory::TransformUsingClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - JoinQualifier result; - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - auto column_list = ExtractParseResultsFromList(extract_parens); - for (auto column : column_list) { - auto col_identifier = column.get().Cast().identifier; - if (col_identifier.empty()) { - throw ParserException("Column identifier cannot be empty"); - } - result.using_columns.push_back(col_identifier); - } - return result; +JoinType PEGTransformerFactory::TransformRightJoin(PEGTransformer &transformer, const bool &has_result) { + return JoinType::RIGHT; } -unique_ptr PEGTransformerFactory::TransformJoinWithoutOnClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto join_prefix = transformer.Transform(list_pr.Child(0)); - auto table_ref = transformer.Transform>(list_pr.Child(2)); - auto result = make_uniq(); - result->ref_type = join_prefix.ref_type; - result->type = join_prefix.join_type; - result->right = std::move(table_ref); - return std::move(result); +JoinType PEGTransformerFactory::TransformSemiJoin(PEGTransformer &transformer) { + return JoinType::SEMI; } -JoinPrefix PEGTransformerFactory::TransformJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0).GetResult()); +JoinType PEGTransformerFactory::TransformAntiJoin(PEGTransformer &transformer) { + return JoinType::ANTI; } -JoinPrefix PEGTransformerFactory::TransformCrossJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result) { - JoinPrefix result; - result.ref_type = JoinRefType::CROSS; - return result; +JoinType PEGTransformerFactory::TransformInnerJoin(PEGTransformer &transformer) { + return JoinType::INNER; } -JoinPrefix PEGTransformerFactory::TransformNaturalJoinPrefix(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - JoinPrefix result; - result.ref_type = JoinRefType::NATURAL; - transformer.TransformOptional(list_pr, 1, result.join_type); - return result; -} +unique_ptr PEGTransformerFactory::TransformTableFunctionLateralOpt( + PEGTransformer &transformer, const optional &lateral, const QualifiedName &qualified_table_function, + vector table_function_arguments, const optional &with_ordinality, + const optional &table_alias) { + auto result = make_uniq(); -JoinPrefix PEGTransformerFactory::TransformPositionalJoinPrefix(PEGTransformer &transformer, - ParseResult &parse_result) { - JoinPrefix result; - result.ref_type = JoinRefType::POSITIONAL; - return result; -} - -unique_ptr PEGTransformerFactory::TransformInnerTableRef(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformTableFunction(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformTableFunctionLateralOpt(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - - auto result = make_uniq(); - - auto qualified_table_function = transformer.Transform(list_pr.Child(1)); - auto table_function_arguments = transformer.Transform>(list_pr.Child(2)); - result->with_ordinality = list_pr.Child(3).HasResult() ? OrdinalityType::WITH_ORDINALITY - : OrdinalityType::WITHOUT_ORDINALITY; + result->with_ordinality = + with_ordinality.value_or(false) ? OrdinalityType::WITH_ORDINALITY : OrdinalityType::WITHOUT_ORDINALITY; result->function = make_uniq(qualified_table_function.catalog, qualified_table_function.schema, qualified_table_function.name, std::move(table_function_arguments)); - auto &table_alias_opt = list_pr.Child(4); - if (table_alias_opt.HasResult()) { - auto table_alias = transformer.Transform(table_alias_opt.GetResult()); - result->alias = table_alias.name; - result->column_name_alias = table_alias.column_name_alias; + if (table_alias) { + result->alias = table_alias->name; + result->column_name_alias = table_alias->column_name_alias; } return std::move(result); } -unique_ptr PEGTransformerFactory::TransformTableFunctionAliasColon(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - - auto table_alias = transformer.Transform(list_pr.Child(0)); - - auto qualified_table_function = transformer.Transform(list_pr.Child(1)); - auto table_function_arguments = transformer.Transform>(list_pr.Child(2)); - +unique_ptr PEGTransformerFactory::TransformTableFunctionAliasColon( + PEGTransformer &transformer, const Identifier &table_alias_colon, const QualifiedName &qualified_table_function, + vector table_function_arguments, const optional &with_ordinality, + optional> sample_clause) { auto result = make_uniq(); - result->with_ordinality = list_pr.Child(3).HasResult() ? OrdinalityType::WITH_ORDINALITY - : OrdinalityType::WITHOUT_ORDINALITY; + result->with_ordinality = + with_ordinality.value_or(false) ? OrdinalityType::WITH_ORDINALITY : OrdinalityType::WITHOUT_ORDINALITY; result->function = make_uniq(qualified_table_function.catalog, qualified_table_function.schema, qualified_table_function.name, std::move(table_function_arguments)); - result->alias = Identifier(table_alias); - transformer.TransformOptional>(list_pr, 4, result->sample); - return std::move(result); -} - -string PEGTransformerFactory::TransformTableAliasColon(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0)); -} - -QualifiedName PEGTransformerFactory::TransformQualifiedTableFunction(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - QualifiedName result; - auto &opt_catalog = list_pr.Child(0); - if (opt_catalog.HasResult()) { - result.catalog = transformer.Transform(opt_catalog.GetResult()); - } else { - result.catalog = INVALID_CATALOG; - } - auto &opt_schema = list_pr.Child(1); - if (opt_schema.HasResult()) { - result.schema = transformer.Transform(opt_schema.GetResult()); - } else { - result.schema = INVALID_SCHEMA; - } - if (!result.catalog.empty() && result.schema.empty()) { - result.schema = result.catalog; - result.catalog = INVALID_CATALOG; - } - result.name = list_pr.Child(2).identifier; - return result; -} - -unique_ptr PEGTransformerFactory::TransformTableSubquery(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto subquery_reference = transformer.Transform>(list_pr.Child(1)); - auto &table_alias_opt = list_pr.Child(2); - if (table_alias_opt.HasResult()) { - auto table_alias = transformer.Transform(table_alias_opt.GetResult()); - subquery_reference->alias = table_alias.name; - subquery_reference->column_name_alias = table_alias.column_name_alias; + result->alias = table_alias_colon; + if (sample_clause) { + result->sample = std::move(*sample_clause); } - return subquery_reference; -} - -unique_ptr PEGTransformerFactory::TransformSubqueryReference(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(0)); - auto select_statement = transformer.Transform>(extract_parens); - auto subquery_ref = make_uniq(std::move(select_statement)); - return std::move(subquery_ref); -} - -unique_ptr PEGTransformerFactory::TransformBaseTableRef(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto result = transformer.Transform>(list_pr.Child(1)); - auto &table_alias_colon_opt = list_pr.Child(0); - if (table_alias_colon_opt.HasResult()) { - result->alias = transformer.Transform(table_alias_colon_opt.GetResult()); - } - auto &table_alias_opt = list_pr.Child(2); - if (table_alias_opt.HasResult() && table_alias_colon_opt.HasResult()) { - throw ParserException("Table reference %s cannot have two aliases", result->ToString()); - } - if (table_alias_opt.HasResult()) { - auto table_alias = transformer.Transform(table_alias_opt.GetResult()); - result->alias = table_alias.name; - result->column_name_alias = table_alias.column_name_alias; - } - transformer.TransformOptional>(list_pr, 3, result->at_clause); - transformer.TransformOptional>(list_pr, 4, result->sample); return std::move(result); } -unique_ptr PEGTransformerFactory::TransformParensTableRef(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - auto table_ref = transformer.Transform>(extract_parens); - auto &table_alias_colon_opt = list_pr.Child(0); - auto &table_alias_opt = list_pr.Child(2); - if (table_alias_colon_opt.HasResult() && table_alias_opt.HasResult()) { - throw ParserException("Table reference %s cannot have two aliases", table_ref->ToString()); - } - if (!table_alias_colon_opt.HasResult() && !table_alias_opt.HasResult()) { - return table_ref; - } - auto select_statement = make_uniq(); - auto select_node = make_uniq(); - select_node->select_list.push_back(make_uniq()); - select_node->from_table = std::move(table_ref); - select_statement->node = std::move(select_node); - auto subquery = make_uniq(std::move(select_statement)); - if (table_alias_colon_opt.HasResult()) { - subquery->alias = transformer.Transform(table_alias_colon_opt.GetResult()); - } - if (table_alias_opt.HasResult()) { - auto table_alias = transformer.Transform(table_alias_opt.GetResult()); - subquery->alias = table_alias.name; - subquery->column_name_alias = table_alias.column_name_alias; - } - transformer.TransformOptional>(list_pr, 3, subquery->sample); - return std::move(subquery); -} - -unique_ptr PEGTransformerFactory::TransformAtClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - return transformer.Transform>(extract_parens); -} - -unique_ptr PEGTransformerFactory::TransformAtSpecifier(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto unit = transformer.Transform(list_pr.Child(0)); - auto expr = transformer.Transform>(list_pr.Child(2)); - return make_uniq(unit, std::move(expr)); -} - -string PEGTransformerFactory::TransformAtUnit(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - return choice_pr.GetResult().Cast().keyword; -} - -unique_ptr PEGTransformerFactory::TransformValuesRef(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto values_select_statement = - transformer.Transform>(list_pr.Child(0)); - auto subquery_ref = make_uniq(std::move(values_select_statement)); - auto &opt_alias = list_pr.Child(1); - if (opt_alias.HasResult()) { - auto table_alias = transformer.Transform(opt_alias.GetResult()); - subquery_ref->alias = table_alias.name; - subquery_ref->column_name_alias = table_alias.column_name_alias; - } - return std::move(subquery_ref); -} - -unique_ptr PEGTransformerFactory::TransformValuesClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - - auto value_expression_list = ExtractParseResultsFromList(list_pr.Child(1)); - vector>> values_list; - for (auto value_expression : value_expression_list) { - values_list.push_back(transformer.Transform>>(value_expression)); - } - if (values_list.size() > 1) { - const auto expected_size = values_list[0].size(); - for (idx_t i = 1; i < values_list.size(); i++) { - if (values_list[i].size() != expected_size) { - throw ParserException( - *values_list[i][0], - "VALUES lists must all be the same length, expected %d %s but found a list with %d %s", - expected_size, expected_size == 1 ? "entry" : "entries", values_list[i].size(), - values_list[i].size() == 1 ? "entry" : "entries"); - } - } - } - auto result = make_uniq(); - result->alias = "valueslist"; - result->values = std::move(values_list); - - auto select_node = make_uniq(); - select_node->from_table = std::move(result); - select_node->select_list.push_back(make_uniq()); - auto select_statement = make_uniq(); - select_statement->node = std::move(select_node); - return select_statement; -} - -vector> PEGTransformerFactory::TransformValuesExpressions(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> result; - auto &extract_parens = ExtractResultFromParens(list_pr.Child(0)); - auto expression_list = ExtractParseResultsFromList(extract_parens); - for (auto expression : expression_list) { - result.push_back(transformer.Transform>(expression)); - } - return result; -} - -unique_ptr PEGTransformerFactory::TransformTableStatement(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto result = make_uniq(); - auto node = make_uniq(); - node->select_list.push_back(make_uniq()); - node->from_table = transformer.Transform>(list_pr.Child(1)); - result->node = std::move(node); - return result; -} - -vector PEGTransformerFactory::TransformOrderByClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(2)); -} - -vector PEGTransformerFactory::TransformOrderByExpressions(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -vector PEGTransformerFactory::TransformOrderByExpressionList(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector result; - auto expr_list = ExtractParseResultsFromList(list_pr.Child(0)); - for (auto expr : expr_list) { - result.push_back(transformer.Transform(expr)); - } - return result; -} - -vector PEGTransformerFactory::TransformOrderByAll(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector result; - auto order_type = OrderType::ORDER_DEFAULT; - auto &order_type_pr = list_pr.Child(1); - if (order_type_pr.HasResult()) { - order_type = transformer.Transform(order_type_pr.GetResult()); - } - auto order_by_null_type = OrderByNullType::ORDER_DEFAULT; - auto &order_by_null_pr = list_pr.Child(2); - if (order_by_null_pr.HasResult()) { - order_by_null_type = transformer.Transform(order_by_null_pr.GetResult()); - } - auto star_expr = make_uniq(); - star_expr->IsColumnsMutable() = true; - result.push_back(OrderByNode(order_type, order_by_null_type, std::move(star_expr))); - return result; +string PEGTransformerFactory::TransformVersionAtUnit(PEGTransformer &transformer) { + return "VERSION"; } -OrderByNode PEGTransformerFactory::TransformOrderByExpression(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expr = transformer.Transform>(list_pr.Child(0)); - auto order_type = OrderType::ORDER_DEFAULT; - transformer.TransformOptional(list_pr, 1, order_type); - auto order_by_null_type = OrderByNullType::ORDER_DEFAULT; - transformer.TransformOptional(list_pr, 2, order_by_null_type); - return OrderByNode(order_type, order_by_null_type, std::move(expr)); +string PEGTransformerFactory::TransformTimestampAtUnit(PEGTransformer &transformer) { + return "TIMESTAMP"; } -OrderType PEGTransformerFactory::TransformDescOrAsc(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.TransformEnum(list_pr.Child(0).GetResult()); +OrderType PEGTransformerFactory::TransformDescendingOrder(PEGTransformer &transformer) { + return OrderType::DESCENDING; } -OrderByNullType PEGTransformerFactory::TransformNullsFirstOrLast(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.TransformEnum(list_pr.Child(0).GetResult()); +OrderType PEGTransformerFactory::TransformAscendingOrder(PEGTransformer &transformer) { + return OrderType::ASCENDING; } -vector> PEGTransformerFactory::TransformResultModifiers(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> result; - vector order_by; - transformer.TransformOptional>(list_pr, 0, order_by); - if (!order_by.empty()) { - auto order_modifier = make_uniq(); - order_modifier->orders = std::move(order_by); - result.push_back(std::move(order_modifier)); - } - unique_ptr limit_offset; - transformer.TransformOptional>(list_pr, 1, limit_offset); - if (limit_offset) { - result.push_back(std::move(limit_offset)); - } - return result; +OrderByNullType PEGTransformerFactory::TransformNullsFirst(PEGTransformer &transformer) { + return OrderByNullType::NULLS_FIRST; } -unique_ptr PEGTransformerFactory::TransformLimitOffset(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); +OrderByNullType PEGTransformerFactory::TransformNullsLast(PEGTransformer &transformer) { + return OrderByNullType::NULLS_LAST; } unique_ptr PEGTransformerFactory::VerifyLimitOffset(LimitPercentResult &limit, @@ -1295,88 +643,19 @@ unique_ptr PEGTransformerFactory::VerifyLimitOffset(LimitPercent return std::move(result); } -unique_ptr PEGTransformerFactory::TransformOffsetLimitClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto offset = transformer.Transform(list_pr.Child(0)); - LimitPercentResult limit; - transformer.TransformOptional(list_pr, 1, limit); - return VerifyLimitOffset(limit, offset); -} - -unique_ptr PEGTransformerFactory::TransformLimitOffsetClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto limit = transformer.Transform(list_pr.Child(0)); - LimitPercentResult offset; - transformer.TransformOptional(list_pr, 1, offset); - return VerifyLimitOffset(limit, offset); -} - -LimitPercentResult PEGTransformerFactory::TransformLimitClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(1)); -} - -LimitPercentResult PEGTransformerFactory::TransformLimitValue(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(0).GetResult()); -} - -LimitPercentResult PEGTransformerFactory::TransformLimitAll(PEGTransformer &transformer, ParseResult &parse_result) { - // LIMIT ALL is represented as a NULL constant, matching PostgreSQL behavior (makeNullAConst) - LimitPercentResult result; - result.expression = make_uniq(Value()); - result.is_percent = false; - return result; -} - -LimitPercentResult PEGTransformerFactory::TransformLimitLiteralPercent(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - LimitPercentResult result; - // TODO(Dtenwolde) transform number literal properly - result.expression = make_uniq(Value(list_pr.Child(0).number)); - result.is_percent = true; - return result; -} - LimitPercentResult PEGTransformerFactory::TransformLimitExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); + unique_ptr expression, + const bool &has_result) { LimitPercentResult result; - result.expression = transformer.Transform>(list_pr.Child(0)); - result.is_percent = list_pr.Child(1).HasResult(); + result.expression = std::move(expression); + result.is_percent = has_result; return result; } -LimitPercentResult PEGTransformerFactory::TransformOffsetClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(1)); -} - -GroupByNode PEGTransformerFactory::TransformGroupByClause(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform(list_pr.Child(2)); -} - struct GroupingExpressionMap { parsed_expression_map_t map; }; -GroupByNode PEGTransformerFactory::TransformGroupByExpressions(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto result = transformer.Transform(list_pr.Child(0).GetResult()); - return result; -} - -GroupByNode PEGTransformerFactory::TransformGroupByAll(PEGTransformer &transformer, ParseResult &parse_result) { - GroupByNode result; - result.group_expressions.push_back(make_uniq()); - return result; -} - static void CheckGroupingSetMax(idx_t count) { static constexpr const idx_t MAX_GROUPING_SETS = 65535; if (count > MAX_GROUPING_SETS) { @@ -1434,42 +713,30 @@ static void AddCubeSets(const GroupingSet ¤t_set, vector &cub } } -vector PEGTransformerFactory::GroupByExpressionUnfolding(PEGTransformer &transformer, - ParseResult &group_by_expr, +vector PEGTransformerFactory::GroupByExpressionUnfolding(GroupByExpressionInfo &group_by_expr, GroupingExpressionMap &map, GroupByNode &result) { vector result_sets; - if (StringUtil::CIEquals(group_by_expr.name, "EmptyGroupingItem")) { + if (group_by_expr.type == GroupByExpressionInfoType::EMPTY) { result_sets.emplace_back(); - } else if (StringUtil::CIEquals(group_by_expr.name, "Expression")) { + } else if (group_by_expr.type == GroupByExpressionInfoType::EXPRESSION) { vector indexes; - auto expr = transformer.Transform>(group_by_expr); - AddGroupByExpression(std::move(expr), map, result, indexes); + AddGroupByExpression(std::move(group_by_expr.expression), map, result, indexes); result_sets.push_back(VectorToGroupingSet(indexes)); - } else if (StringUtil::CIEquals(group_by_expr.name, "GroupingSetsClause")) { - auto &grouping_set_list = group_by_expr.Cast(); - auto &inner_group_by_list = ExtractResultFromParens(grouping_set_list.Child(2)); - auto &list_pr = inner_group_by_list.Cast(); - auto group_by_list = ExtractParseResultsFromList(list_pr.Child(0)); - for (auto &child_wrapper : group_by_list) { - auto &child_list_pr = child_wrapper.get().Cast(); - auto &child_expr = child_list_pr.Child(0).GetResult(); - auto child_sets = GroupByExpressionUnfolding(transformer, child_expr, map, result); + } else if (group_by_expr.type == GroupByExpressionInfoType::GROUPING_SETS) { + for (auto &child_expr : group_by_expr.children) { + auto child_sets = GroupByExpressionUnfolding(child_expr, map, result); result_sets.insert(result_sets.end(), child_sets.begin(), child_sets.end()); } - } else if (StringUtil::CIEquals(group_by_expr.name, "CubeOrRollupClause")) { - auto &group_by_list = group_by_expr.Cast(); - auto type_str = transformer.Transform(group_by_list.Child(0)); - auto &extract_parens = ExtractResultFromParens(group_by_list.Child(1)); - if (!extract_parens.Cast().HasResult()) { + } else if (group_by_expr.type == GroupByExpressionInfoType::CUBE || + group_by_expr.type == GroupByExpressionInfoType::ROLLUP) { + if (group_by_expr.expressions.empty()) { throw ParserException("CUBE or ROLLUP column list cannot be empty"); } - auto expr_list = ExtractParseResultsFromList(extract_parens.Cast().GetResult()); vector unfolding_sets; - for (auto &expr_node : expr_list) { + for (auto &expr : group_by_expr.expressions) { vector indexes; - auto expr = transformer.Transform>(expr_node); AddGroupByExpression(std::move(expr), map, result, indexes); GroupingSet s; @@ -1479,11 +746,11 @@ vector PEGTransformerFactory::GroupByExpressionUnfolding(PEGTransfo unfolding_sets.push_back(std::move(s)); } - if (StringUtil::CIEquals(type_str, "CUBE")) { + if (group_by_expr.type == GroupByExpressionInfoType::CUBE) { CheckGroupingSetCubes(result_sets.size(), unfolding_sets.size()); GroupingSet current_set; AddCubeSets(current_set, unfolding_sets, result_sets, 0); - } else if (StringUtil::CIEquals(type_str, "ROLLUP")) { + } else { GroupingSet current_set; result_sets.push_back(current_set); for (idx_t i = 0; i < unfolding_sets.size(); i++) { @@ -1495,24 +762,21 @@ vector PEGTransformerFactory::GroupByExpressionUnfolding(PEGTransfo return result_sets; } -string PEGTransformerFactory::TransformCubeOrRollup(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0).GetResult(); - return choice_pr.Cast().keyword; +string PEGTransformerFactory::TransformCubeKeyword(PEGTransformer &transformer) { + return "CUBE"; } -GroupByNode PEGTransformerFactory::TransformGroupByList(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto group_by_list = ExtractParseResultsFromList(list_pr.Child(0)); +string PEGTransformerFactory::TransformRollupKeyword(PEGTransformer &transformer) { + return "ROLLUP"; +} +GroupByNode PEGTransformerFactory::TransformGroupByList(PEGTransformer &transformer, + vector group_by_expression) { GroupByNode result; GroupingExpressionMap map; - for (auto group_by_child : group_by_list) { - auto &group_by_expr_child_list = group_by_child.get().Cast(); - auto &group_by_expr = group_by_expr_child_list.Child(0).GetResult(); - - vector next_sets = GroupByExpressionUnfolding(transformer, group_by_expr, map, result); + for (auto &group_by_expr : group_by_expression) { + vector next_sets = GroupByExpressionUnfolding(group_by_expr, map, result); if (result.grouping_sets.empty()) { result.grouping_sets = std::move(next_sets); @@ -1536,25 +800,39 @@ GroupByNode PEGTransformerFactory::TransformGroupByList(PEGTransformer &transfor return result; } -unique_ptr PEGTransformerFactory::TransformGroupByExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); +GroupByExpressionInfo PEGTransformerFactory::TransformGroupByBaseExpression(PEGTransformer &transformer, + unique_ptr expression) { + GroupByExpressionInfo result; + result.type = GroupByExpressionInfoType::EXPRESSION; + result.expression = std::move(expression); + return result; } -unique_ptr PEGTransformerFactory::TransformEmptyGroupingItem(PEGTransformer &transformer, - ParseResult &parse_result) { - throw NotImplementedException("Rule 'EmptyGroupingItem' has not been implemented yet"); +GroupByExpressionInfo PEGTransformerFactory::TransformEmptyGroupingItem(PEGTransformer &transformer) { + GroupByExpressionInfo result; + result.type = GroupByExpressionInfoType::EMPTY; + return result; } -unique_ptr PEGTransformerFactory::TransformCubeOrRollupClause(PEGTransformer &transformer, - ParseResult &parse_result) { - throw NotImplementedException("Rule 'CubeOrRollupClause' has not been implemented yet"); +GroupByExpressionInfo +PEGTransformerFactory::TransformCubeOrRollupClause(PEGTransformer &transformer, const string &cube_or_rollup, + optional>> expression) { + GroupByExpressionInfo result; + result.type = StringUtil::CIEquals(cube_or_rollup, "CUBE") ? GroupByExpressionInfoType::CUBE + : GroupByExpressionInfoType::ROLLUP; + if (expression) { + result.expressions = std::move(*expression); + } + return result; } -unique_ptr PEGTransformerFactory::TransformGroupingSetsClause(PEGTransformer &transformer, - ParseResult &parse_result) { - throw NotImplementedException("Rule 'GroupingSetsClause' has not been implemented yet"); +GroupByExpressionInfo +PEGTransformerFactory::TransformGroupingSetsClause(PEGTransformer &transformer, + vector group_by_expression) { + GroupByExpressionInfo result; + result.type = GroupByExpressionInfoType::GROUPING_SETS; + result.children = std::move(group_by_expression); + return result; } CommonTableExpressionMap PEGTransformerFactory::TransformWithClause(PEGTransformer &transformer, @@ -1565,8 +843,8 @@ CommonTableExpressionMap PEGTransformerFactory::TransformWithClause(PEGTransform CommonTableExpressionMap result; for (idx_t entry_idx = 0; entry_idx < with_statement_list.size(); entry_idx++) { - auto with_entry = - transformer.Transform>>(with_statement_list[entry_idx]); + auto with_entry = transformer.Transform>>( + with_statement_list[entry_idx]); if (is_recursive) { auto &query_node = with_entry.second->query_node; @@ -1579,68 +857,66 @@ CommonTableExpressionMap PEGTransformerFactory::TransformWithClause(PEGTransform throw ParserException("Recursive CTEs with DML statements are not supported"); } // Now safe to call on SELECT, VALUES, etc. - query_node = ToRecursiveCTE(std::move(query_node), Identifier(with_entry.first), with_entry.second->aliases, + query_node = ToRecursiveCTE(std::move(query_node), with_entry.first, with_entry.second->aliases, with_entry.second->key_targets); } - auto cte_name = string(with_entry.first); + auto &cte_name = with_entry.first; - auto it = result.map.find(Identifier(cte_name)); + auto it = result.map.find(cte_name); if (it != result.map.end()) { // can't have two CTEs with same name - throw ParserException("Duplicate CTE name \"%s\"", cte_name); + throw ParserException("Duplicate CTE name \"%s\"", cte_name.GetIdentifierName()); } - result.map.insert(Identifier(with_entry.first), std::move(with_entry.second)); + result.map.insert(with_entry.first, std::move(with_entry.second)); } return result; } -pair> -PEGTransformerFactory::TransformWithStatement(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); +pair> +PEGTransformerFactory::TransformWithStatement(PEGTransformer &transformer, const Identifier &col_id_or_string, + const optional> &insert_column_list, + optional>> using_key, + const optional &materialized, unique_ptr cte_body) { auto result = make_uniq(); - auto cte_name = transformer.Transform(list_pr.Child(0)); - transformer.TransformOptional>(list_pr, 1, result->aliases); - transformer.TransformOptional>>(list_pr, 2, result->key_targets); - auto &materialized_opt = list_pr.Child(4); - if (materialized_opt.HasResult()) { + auto cte_name = col_id_or_string; + if (insert_column_list) { + result->aliases = StringsToIdentifiers(*insert_column_list); + } + if (using_key) { + result->key_targets = std::move(*using_key); + } + if (materialized) { // If this has a result, we know it is either NEVER or ALWAYS - bool not_materialized = transformer.Transform(materialized_opt.GetResult()); - if (not_materialized) { + if (*materialized) { result->materialized = CTEMaterialize::CTE_MATERIALIZE_NEVER; } else { result->materialized = CTEMaterialize::CTE_MATERIALIZE_ALWAYS; } } - auto table_ref = transformer.Transform>(list_pr.Child(5)); - D_ASSERT(table_ref->type == TableReferenceType::SUBQUERY); - auto subquery_ref = unique_ptr_cast(std::move(table_ref)); + D_ASSERT(cte_body->type == TableReferenceType::SUBQUERY); + auto subquery_ref = unique_ptr_cast(std::move(cte_body)); result->query_node = std::move(subquery_ref->subquery->node); return make_pair(cte_name, std::move(result)); } -unique_ptr PEGTransformerFactory::TransformCTEBody(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - // CTEBody <- Parens(CTEBodyContent) - auto &inner = ExtractResultFromParens(list_pr.Child(0)); - // CTEBodyContent <- SelectStatementInternal / Statement - auto &content_list = inner.Cast(); - auto &body_choice = content_list.Child(0); - if (body_choice.GetResult().name == "SelectStatementInternal") { - auto select_statement = transformer.Transform>(body_choice.GetResult()); - return make_uniq(std::move(select_statement)); - } - // DML body (INSERT / UPDATE / DELETE) - transform as a Statement and extract its QueryNode - auto sql_stmt = transformer.Transform>(body_choice.GetResult()); +unique_ptr +PEGTransformerFactory::TransformCTESelectBody(PEGTransformer &transformer, + unique_ptr select_statement_internal) { + return make_uniq(std::move(select_statement_internal)); +} + +unique_ptr PEGTransformerFactory::TransformCTEDMLBody(PEGTransformer &transformer, + unique_ptr statement) { unique_ptr query_node; - switch (sql_stmt->type) { + switch (statement->type) { case StatementType::INSERT_STATEMENT: - query_node = unique_ptr_cast(std::move(sql_stmt->Cast().node)); + query_node = unique_ptr_cast(std::move(statement->Cast().node)); break; case StatementType::UPDATE_STATEMENT: - query_node = unique_ptr_cast(std::move(sql_stmt->Cast().node)); + query_node = unique_ptr_cast(std::move(statement->Cast().node)); break; case StatementType::DELETE_STATEMENT: - query_node = unique_ptr_cast(std::move(sql_stmt->Cast().node)); + query_node = unique_ptr_cast(std::move(statement->Cast().node)); break; default: throw ParserException("A CTE body must be a SELECT, INSERT, UPDATE, or DELETE statement"); @@ -1650,47 +926,8 @@ unique_ptr PEGTransformerFactory::TransformCTEBody(PEGTransformer &tra return make_uniq(std::move(select_statement)); } -bool PEGTransformerFactory::TransformMaterialized(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto ¬_opt = list_pr.Child(0); - return not_opt.HasResult(); -} - -vector> PEGTransformerFactory::TransformUsingKey(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(2)); - return transformer.Transform>>(extract_parens); -} - -unique_ptr PEGTransformerFactory::TransformHavingClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(1)); -} - -LimitPercentResult PEGTransformerFactory::TransformOffsetValue(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - LimitPercentResult result; - result.expression = transformer.Transform>(list_pr.Child(0)); - return result; -} - -unique_ptr PEGTransformerFactory::TransformQualifyClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(1)); -} - -vector> PEGTransformerFactory::TransformWindowClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto window_list = ExtractParseResultsFromList(list_pr.Child(1)); - vector> result; - for (auto &window : window_list) { - result.push_back(transformer.Transform>(window)); - } - return result; +bool PEGTransformerFactory::TransformMaterialized(PEGTransformer &transformer, const bool &has_result) { + return has_result; } unique_ptr PEGTransformerFactory::TransformWindowDefinition(PEGTransformer &transformer, @@ -1703,43 +940,25 @@ unique_ptr PEGTransformerFactory::TransformWindowDefinition(PE return std::move(window_function); } -unique_ptr PEGTransformerFactory::TransformSampleClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(1)); -} - -unique_ptr PEGTransformerFactory::TransformSampleEntry(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); -} - -unique_ptr PEGTransformerFactory::TransformSampleEntryFunction(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.Child(1)); - auto result = transformer.Transform>(extract_parens); - transformer.TransformOptional(list_pr, 0, result->method); - auto &repeatable_sample_opt = list_pr.Child(2); - if (repeatable_sample_opt.HasResult()) { - auto repeatable_seed = transformer.Transform(repeatable_sample_opt.GetResult()); - result->seed = repeatable_seed; - result->repeatable = true; +unique_ptr PEGTransformerFactory::TransformSampleEntryFunction( + PEGTransformer &transformer, const optional &sample_function, unique_ptr sample_count, + const optional &repeatable_sample) { + if (sample_function) { + sample_count->method = *sample_function; } - return result; + if (repeatable_sample) { + sample_count->seed = *repeatable_sample; + sample_count->repeatable = true; + } + return sample_count; } -unique_ptr PEGTransformerFactory::TransformSampleEntryCount(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_count = transformer.Transform>(list_pr.Child(0)); - auto &optional_properties = list_pr.Child(1); - if (optional_properties.HasResult()) { - auto &extract_parens = ExtractResultFromParens(optional_properties.GetResult()).Cast(); - auto properties = transformer.Transform>(extract_parens); - sample_count->method = properties.first; - sample_count->seed = properties.second; +unique_ptr +PEGTransformerFactory::TransformSampleEntryCount(PEGTransformer &transformer, unique_ptr sample_count, + const optional> &sample_properties) { + if (sample_properties) { + sample_count->method = sample_properties->first; + sample_count->seed = sample_properties->second; if (sample_count->seed.IsValid()) { sample_count->repeatable = true; } @@ -1747,35 +966,495 @@ unique_ptr PEGTransformerFactory::TransformSampleEntryCount(PEGTr return sample_count; } -SampleMethod PEGTransformerFactory::TransformSampleFunction(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto method = transformer.Transform(list_pr.Child(0)); - return EnumUtil::FromString(method); +bool PEGTransformerFactory::TransformSamplePercentage(PEGTransformer &transformer) { + return true; } -unique_ptr PEGTransformerFactory::TransformSampleCount(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto result = make_uniq(); - auto expr = transformer.Transform>(list_pr.Child(0)); - if (expr->GetExpressionClass() != ExpressionClass::CONSTANT) { - throw ParserException(expr->GetQueryLocation(), "Only constants are supported in sample clause currently"); +bool PEGTransformerFactory::TransformSampleRows(PEGTransformer &transformer) { + return false; +} + +unique_ptr +PEGTransformerFactory::TransformSelectParens(PEGTransformer &transformer, + unique_ptr select_statement_internal) { + return select_statement_internal; +} + +vector> +PEGTransformerFactory::TransformResultModifiers(PEGTransformer &transformer, + optional> order_by_clause, + optional> limit_offset) { + vector> result; + if (order_by_clause) { + auto order_modifier = make_uniq(); + order_modifier->orders = std::move(*order_by_clause); + result.push_back(std::move(order_modifier)); } - auto &const_expr = expr->Cast(); - auto &sample_value = const_expr.GetValue(); - transformer.TransformOptional(list_pr, 1, result->is_percentage); + if (limit_offset) { + result.push_back(std::move(*limit_offset)); + } + return result; +} + +unique_ptr +PEGTransformerFactory::TransformLimitOffsetClause(PEGTransformer &transformer, LimitPercentResult limit_clause, + optional offset_clause) { + LimitPercentResult empty_offset; + return VerifyLimitOffset(limit_clause, offset_clause ? *offset_clause : empty_offset); +} + +unique_ptr +PEGTransformerFactory::TransformOffsetLimitClause(PEGTransformer &transformer, LimitPercentResult offset_clause, + optional limit_clause) { + LimitPercentResult empty_limit; + return VerifyLimitOffset(limit_clause ? *limit_clause : empty_limit, offset_clause); +} + +unique_ptr PEGTransformerFactory::TransformTableStatement(PEGTransformer &transformer, + unique_ptr base_table_name) { + auto result = make_uniq(); + auto node = make_uniq(); + node->select_list.push_back(make_uniq()); + node->from_table = std::move(base_table_name); + result->node = std::move(node); + return result; +} + +unique_ptr +PEGTransformerFactory::TransformSimpleSelectParens(PEGTransformer &transformer, + unique_ptr simple_select) { + return simple_select; +} + +unique_ptr PEGTransformerFactory::TransformSelectFromClause(PEGTransformer &transformer, + unique_ptr select_clause, + optional> from_clause) { + if (from_clause) { + select_clause->from_table = std::move(*from_clause); + } else { + select_clause->from_table = make_uniq(); + } + return select_clause; +} + +unique_ptr +PEGTransformerFactory::TransformFromSelectClause(PEGTransformer &transformer, unique_ptr from_clause, + optional> select_clause) { + unique_ptr result; + if (!select_clause) { + result = make_uniq(); + result->select_list.push_back(make_uniq()); + } else { + result = std::move(*select_clause); + } + result->from_table = std::move(from_clause); + return result; +} + +vector> +PEGTransformerFactory::TransformUsingKey(PEGTransformer &transformer, + vector> target_list) { + return target_list; +} + +unique_ptr +PEGTransformerFactory::TransformSelectClause(PEGTransformer &transformer, optional distinct_clause, + optional>> target_list) { + auto result = make_uniq(); + if (distinct_clause && distinct_clause->is_distinct) { + auto distinct_modifier = make_uniq(); + for (auto &distinct_on : distinct_clause->distinct_targets) { + distinct_modifier->distinct_on_targets.push_back(distinct_on->Copy()); + } + result->modifiers.push_back(std::move(distinct_modifier)); + } + if (!target_list) { + throw ParserException("SELECT clause without selection list"); + } + for (auto &expr_ptr : *target_list) { + result->select_list.push_back(std::move(expr_ptr)); + } + return result; +} + +vector> +PEGTransformerFactory::TransformTargetList(PEGTransformer &transformer, + vector> aliased_expression) { + return aliased_expression; +} + +vector PEGTransformerFactory::TransformColumnAliases(PEGTransformer &transformer, + const vector &col_id_or_string) { + return IdentifiersToStrings(col_id_or_string); +} + +DistinctClause PEGTransformerFactory::TransformDistinctAll(PEGTransformer &transformer) { + DistinctClause result; + result.is_distinct = false; + return result; +} + +DistinctClause +PEGTransformerFactory::TransformDistinctOn(PEGTransformer &transformer, + optional>> distinct_on_targets) { + DistinctClause result; + result.is_distinct = true; + if (distinct_on_targets) { + result.distinct_targets = std::move(*distinct_on_targets); + } + return result; +} + +vector> +PEGTransformerFactory::TransformDistinctOnTargets(PEGTransformer &transformer, + vector> expression) { + return expression; +} + +unique_ptr PEGTransformerFactory::TransformTableSubquery(PEGTransformer &transformer, + const optional &lateral, + unique_ptr subquery_reference, + const optional &table_alias) { + if (table_alias) { + subquery_reference->alias = table_alias->name; + subquery_reference->column_name_alias = table_alias->column_name_alias; + } + return subquery_reference; +} + +unique_ptr PEGTransformerFactory::TransformBaseTableRef(PEGTransformer &transformer, + const optional &table_alias_colon, + unique_ptr base_table_name, + const optional &table_alias, + optional> at_clause, + optional> sample_clause) { + if (table_alias_colon) { + base_table_name->alias = *table_alias_colon; + } + if (table_alias && table_alias_colon) { + throw ParserException("Table reference %s cannot have two aliases", base_table_name->ToString()); + } + if (table_alias) { + base_table_name->alias = table_alias->name; + base_table_name->column_name_alias = table_alias->column_name_alias; + } + if (at_clause) { + base_table_name->at_clause = std::move(*at_clause); + } + if (sample_clause) { + base_table_name->sample = std::move(*sample_clause); + } + return std::move(base_table_name); +} + +Identifier PEGTransformerFactory::TransformTableAliasColon(PEGTransformer &transformer, + const Identifier &col_id_or_string) { + return col_id_or_string; +} + +unique_ptr PEGTransformerFactory::TransformValuesRef(PEGTransformer &transformer, + unique_ptr values_clause, + const optional &table_alias) { + auto subquery_ref = make_uniq(std::move(values_clause)); + if (table_alias) { + subquery_ref->alias = table_alias->name; + subquery_ref->column_name_alias = table_alias->column_name_alias; + } + return std::move(subquery_ref); +} + +unique_ptr PEGTransformerFactory::TransformParensTableRef(PEGTransformer &transformer, + const optional &table_alias_colon, + unique_ptr table_ref, + const optional &table_alias, + optional> sample_clause) { + if (table_alias_colon && table_alias) { + throw ParserException("Table reference %s cannot have two aliases", table_ref->ToString()); + } + if (!table_alias_colon && !table_alias && !sample_clause) { + return table_ref; + } + auto select_statement = make_uniq(); + auto select_node = make_uniq(); + select_node->select_list.push_back(make_uniq()); + select_node->from_table = std::move(table_ref); + select_statement->node = std::move(select_node); + auto subquery = make_uniq(std::move(select_statement)); + if (table_alias_colon) { + subquery->alias = *table_alias_colon; + } + if (table_alias) { + subquery->alias = table_alias->name; + subquery->column_name_alias = table_alias->column_name_alias; + } + if (sample_clause) { + subquery->sample = std::move(*sample_clause); + } + return std::move(subquery); +} + +vector PEGTransformerFactory::TransformPivotGroupByList(PEGTransformer &transformer, + const vector &col_id_or_string) { + return IdentifiersToStrings(col_id_or_string); +} + +unique_ptr PEGTransformerFactory::TransformPivotHeader(PEGTransformer &transformer, + unique_ptr base_expression) { + return base_expression; +} + +PivotColumn PEGTransformerFactory::TransformUnpivotValueList(PEGTransformer &transformer, + const vector &unpivot_header, + vector unpivot_target_list) { + PivotColumn result; + result.unpivot_names = StringsToIdentifiers(unpivot_header); + if (result.unpivot_names.size() != 1) { + throw ParserException("UNPIVOT requires a single column name for the PIVOT IN clause"); + } + result.entries = std::move(unpivot_target_list); + return result; +} + +vector +PEGTransformerFactory::TransformPivotTargetList(PEGTransformer &transformer, + vector> target_list) { + vector result; + for (auto &target : target_list) { + PivotColumnEntry pivot_entry; + pivot_entry.alias = target->GetAlias(); + bool transformed = TransformPivotInList(target, pivot_entry); + if (!transformed) { + pivot_entry.expr = std::move(target); + } + result.push_back(std::move(pivot_entry)); + } + return result; +} + +vector +PEGTransformerFactory::TransformUnpivotTargetList(PEGTransformer &transformer, + vector> target_list) { + vector result; + for (auto &target : target_list) { + PivotColumnEntry pivot_entry; + pivot_entry.alias = target->GetAlias(); + pivot_entry.expr = std::move(target); + result.push_back(std::move(pivot_entry)); + } + return result; +} + +unique_ptr PEGTransformerFactory::TransformSchemaReservedTable(PEGTransformer &transformer, + const Identifier &schema_qualification, + const Identifier &reserved_table_name) { + const auto description = TableDescription(INVALID_CATALOG, schema_qualification, reserved_table_name); + return make_uniq(description); +} + +unique_ptr PEGTransformerFactory::TransformCatalogReservedSchemaTable( + PEGTransformer &transformer, const Identifier &catalog_qualification, + const Identifier &reserved_schema_qualification, const Identifier &reserved_table_name) { + const auto description = + TableDescription(catalog_qualification, reserved_schema_qualification, reserved_table_name); + return make_uniq(description); +} + +QualifiedName PEGTransformerFactory::TransformQualifiedTableFunction(PEGTransformer &transformer, + const optional &catalog_qualification, + const optional &schema_qualification, + const Identifier &table_function_name) { + QualifiedName result; + result.catalog = catalog_qualification ? *catalog_qualification : INVALID_CATALOG; + result.schema = schema_qualification ? *schema_qualification : INVALID_SCHEMA; + if (!result.catalog.empty() && result.schema.empty()) { + result.schema = result.catalog; + result.catalog = INVALID_CATALOG; + } + result.name = table_function_name; + return result; +} + +vector +PEGTransformerFactory::TransformTableFunctionArguments(PEGTransformer &transformer, + optional> function_argument) { + if (function_argument) { + return std::move(*function_argument); + } + return {}; +} + +TableAlias PEGTransformerFactory::TransformTableAliasAs(PEGTransformer &transformer, + const QualifiedName &identifier_or_string_literal, + const optional> &column_aliases) { + TableAlias result; + result.name = identifier_or_string_literal.name; + if (column_aliases) { + result.column_name_alias = StringsToIdentifiers(*column_aliases); + } + return result; +} + +TableAlias PEGTransformerFactory::TransformTableAliasWithoutAs(PEGTransformer &transformer, + const Identifier &identifier, + const optional> &column_aliases) { + TableAlias result; + result.name = identifier; + if (column_aliases) { + result.column_name_alias = StringsToIdentifiers(*column_aliases); + } + return result; +} + +unique_ptr PEGTransformerFactory::TransformAtClause(PEGTransformer &transformer, + unique_ptr at_specifier) { + return at_specifier; +} + +unique_ptr PEGTransformerFactory::TransformAtSpecifier(PEGTransformer &transformer, const string &at_unit, + unique_ptr expression) { + return make_uniq(at_unit, std::move(expression)); +} + +unique_ptr PEGTransformerFactory::TransformJoinWithoutOnClause(PEGTransformer &transformer, + const JoinPrefix &join_prefix, + unique_ptr table_ref) { + auto result = make_uniq(); + result->ref_type = join_prefix.ref_type; + result->type = join_prefix.join_type; + result->right = std::move(table_ref); + return std::move(result); +} + +JoinQualifier PEGTransformerFactory::TransformOnClause(PEGTransformer &transformer, + unique_ptr expression) { + JoinQualifier result; + result.on_clause = std::move(expression); + return result; +} + +JoinQualifier PEGTransformerFactory::TransformUsingClause(PEGTransformer &transformer, + const vector &column_name) { + JoinQualifier result; + for (auto &col_identifier : column_name) { + if (col_identifier.empty()) { + throw ParserException("Column identifier cannot be empty"); + } + result.using_columns.push_back(col_identifier); + } + return result; +} + +JoinPrefix PEGTransformerFactory::TransformCrossJoinPrefix(PEGTransformer &transformer) { + JoinPrefix result; + result.ref_type = JoinRefType::CROSS; + return result; +} + +JoinPrefix PEGTransformerFactory::TransformNaturalJoinPrefix(PEGTransformer &transformer, + const optional &join_type) { + JoinPrefix result; + result.ref_type = JoinRefType::NATURAL; + result.join_type = join_type.value_or(JoinType::INNER); + return result; +} + +JoinPrefix PEGTransformerFactory::TransformPositionalJoinPrefix(PEGTransformer &transformer) { + JoinPrefix result; + result.ref_type = JoinRefType::POSITIONAL; + return result; +} + +unique_ptr PEGTransformerFactory::TransformFromClause(PEGTransformer &transformer, + vector> table_ref) { + auto result_table_ref = std::move(table_ref[0]); + if (table_ref.size() == 1) { + return result_table_ref; + } + for (idx_t i = 1; i < table_ref.size(); i++) { + auto cross_product = make_uniq(); + cross_product->left = std::move(result_table_ref); + cross_product->right = std::move(table_ref[i]); + cross_product->ref_type = JoinRefType::CROSS; + cross_product->is_implicit = true; + result_table_ref = std::move(cross_product); + } + return result_table_ref; +} + +unique_ptr PEGTransformerFactory::TransformWhereClause(PEGTransformer &transformer, + unique_ptr expression) { + return expression; +} + +GroupByNode PEGTransformerFactory::TransformGroupByClause(PEGTransformer &transformer, + GroupByNode group_by_expressions) { + return group_by_expressions; +} + +unique_ptr PEGTransformerFactory::TransformHavingClause(PEGTransformer &transformer, + unique_ptr expression) { + return expression; +} + +unique_ptr PEGTransformerFactory::TransformQualifyClause(PEGTransformer &transformer, + unique_ptr expression) { + return expression; +} + +unique_ptr PEGTransformerFactory::TransformSampleClause(PEGTransformer &transformer, + unique_ptr sample_entry) { + return sample_entry; +} + +vector> +PEGTransformerFactory::TransformWindowClause(PEGTransformer &transformer, + vector> window_definition) { + return window_definition; +} + +SampleMethod PEGTransformerFactory::TransformSampleFunction(PEGTransformer &transformer, const Identifier &col_id) { + return EnumUtil::FromString(col_id.GetIdentifierName()); +} + +pair +PEGTransformerFactory::TransformSampleProperties(PEGTransformer &transformer, const Identifier &col_id, + const optional &sample_seed) { + return make_pair(EnumUtil::FromString(col_id.GetIdentifierName()), + sample_seed ? *sample_seed : optional_idx()); +} + +optional_idx PEGTransformerFactory::TransformRepeatableSample(PEGTransformer &transformer, + const optional_idx &sample_seed) { + return sample_seed; +} + +optional_idx PEGTransformerFactory::TransformSampleSeed(PEGTransformer &transformer, + unique_ptr number_literal) { + auto const_expr = number_literal->Cast(); + return optional_idx(const_expr.GetValue().GetValue()); +} + +unique_ptr PEGTransformerFactory::TransformSampleCount(PEGTransformer &transformer, + unique_ptr sample_value, + const optional &sample_unit) { + auto result = make_uniq(); + if (sample_value->GetExpressionClass() != ExpressionClass::CONSTANT) { + throw ParserException(sample_value->GetQueryLocation(), + "Only constants are supported in sample clause currently"); + } + auto &const_expr = sample_value->Cast(); + auto &sample_value_const = const_expr.GetValue(); + result->is_percentage = sample_unit.value_or(false); if (result->is_percentage) { - // sample size is given in sample_size: use system sampling - auto percentage = sample_value.GetValue(); + auto percentage = sample_value_const.GetValue(); if (percentage < 0 || percentage > 100) { throw ParserException("Sample sample_size %llf out of range, must be between 0 and 100", percentage); } result->sample_size = Value::DOUBLE(percentage); result->method = SampleMethod::SYSTEM_SAMPLE; } else { - // sample size is given in rows: use reservoir sampling - auto rows = sample_value.GetValue(); - if (rows < 0 || sample_value.GetValue() > SampleOptions::MAX_SAMPLE_ROWS) { + auto rows = sample_value_const.GetValue(); + if (rows < 0 || sample_value_const.GetValue() > SampleOptions::MAX_SAMPLE_ROWS) { throw ParserException("Sample rows %lld out of range, must be between 0 and %lld", rows, SampleOptions::MAX_SAMPLE_ROWS); } @@ -1785,42 +1464,132 @@ unique_ptr PEGTransformerFactory::TransformSampleCount(PEGTransfo return result; } -unique_ptr PEGTransformerFactory::TransformSampleValue(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0).GetResult()); +GroupByNode PEGTransformerFactory::TransformGroupByAll(PEGTransformer &transformer) { + GroupByNode result; + result.group_expressions.push_back(make_uniq()); + return result; } -bool PEGTransformerFactory::TransformSampleUnit(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return transformer.TransformEnum(list_pr.Child(0).GetResult()); +unique_ptr +PEGTransformerFactory::TransformSubqueryReference(PEGTransformer &transformer, + unique_ptr select_statement_internal) { + return make_uniq(std::move(select_statement_internal)); } -pair PEGTransformerFactory::TransformSampleProperties(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_str = transformer.Transform(list_pr.Child(0)); - auto sample_method = EnumUtil::FromString(sample_str); - auto &seed_opt = list_pr.Child(1); - optional_idx seed = optional_idx::Invalid(); - if (seed_opt.HasResult()) { - auto &inner_list = seed_opt.GetResult().Cast(); - seed = transformer.Transform(inner_list.Child(1)); +OrderByNode PEGTransformerFactory::TransformOrderByExpression(PEGTransformer &transformer, + unique_ptr expression, + const optional &desc_or_asc, + const optional &nulls_first_or_last) { + return OrderByNode(desc_or_asc.value_or(OrderType::ORDER_DEFAULT), + nulls_first_or_last.value_or(OrderByNullType::ORDER_DEFAULT), std::move(expression)); +} + +vector PEGTransformerFactory::TransformOrderByClause(PEGTransformer &transformer, + vector order_by_expressions) { + return order_by_expressions; +} + +vector PEGTransformerFactory::TransformOrderByExpressionList(PEGTransformer &transformer, + vector order_by_expression) { + return order_by_expression; +} + +vector PEGTransformerFactory::TransformOrderByAll(PEGTransformer &transformer, + const optional &desc_or_asc, + const optional &nulls_first_or_last) { + vector result; + auto star_expr = make_uniq(); + star_expr->IsColumnsMutable() = true; + result.push_back(OrderByNode(desc_or_asc.value_or(OrderType::ORDER_DEFAULT), + nulls_first_or_last.value_or(OrderByNullType::ORDER_DEFAULT), std::move(star_expr))); + return result; +} + +LimitPercentResult PEGTransformerFactory::TransformLimitClause(PEGTransformer &transformer, + LimitPercentResult limit_value) { + return limit_value; +} + +LimitPercentResult PEGTransformerFactory::TransformOffsetClause(PEGTransformer &transformer, + LimitPercentResult offset_value) { + return offset_value; +} + +LimitPercentResult PEGTransformerFactory::TransformOffsetValue(PEGTransformer &transformer, + unique_ptr expression, + const bool &has_result) { + LimitPercentResult result; + result.expression = std::move(expression); + return result; +} + +LimitPercentResult PEGTransformerFactory::TransformLimitAll(PEGTransformer &transformer) { + LimitPercentResult result; + result.expression = make_uniq(Value()); + result.is_percent = false; + return result; +} + +LimitPercentResult PEGTransformerFactory::TransformLimitLiteralPercent(PEGTransformer &transformer, + unique_ptr number_literal) { + LimitPercentResult result; + result.expression = std::move(number_literal); + result.is_percent = true; + return result; +} + +unique_ptr PEGTransformerFactory::TransformColIdExpression(PEGTransformer &transformer, + const Identifier &col_id, + unique_ptr expression) { + expression->SetAlias(col_id); + return expression; +} + +unique_ptr PEGTransformerFactory::TransformExpressionAsCollabel( + PEGTransformer &transformer, unique_ptr expression, const Identifier &col_label_or_string) { + expression->SetAlias(col_label_or_string); + return expression; +} + +unique_ptr PEGTransformerFactory::TransformExpressionOptIdentifier( + PEGTransformer &transformer, unique_ptr expression, const optional &identifier) { + if (identifier) { + expression->SetAlias(*identifier); } - return make_pair(sample_method, seed); + return expression; } -optional_idx PEGTransformerFactory::TransformRepeatableSample(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &extract_parens = ExtractResultFromParens(list_pr.GetChild(1)); - return transformer.Transform(extract_parens); +unique_ptr +PEGTransformerFactory::TransformValuesClause(PEGTransformer &transformer, + vector>> values_expressions) { + if (values_expressions.size() > 1) { + const auto expected_size = values_expressions[0].size(); + for (idx_t i = 1; i < values_expressions.size(); i++) { + if (values_expressions[i].size() != expected_size) { + throw ParserException( + *values_expressions[i][0], + "VALUES lists must all be the same length, expected %d %s but found a list with %d %s", + expected_size, expected_size == 1 ? "entry" : "entries", values_expressions[i].size(), + values_expressions[i].size() == 1 ? "entry" : "entries"); + } + } + } + auto result = make_uniq(); + result->alias = "valueslist"; + result->values = std::move(values_expressions); + + auto select_node = make_uniq(); + select_node->from_table = std::move(result); + select_node->select_list.push_back(make_uniq()); + auto select_statement = make_uniq(); + select_statement->node = std::move(select_node); + return select_statement; } -optional_idx PEGTransformerFactory::TransformSampleSeed(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expr = transformer.Transform>(list_pr.GetChild(0)); - auto const_expr = expr->Cast(); - return optional_idx(const_expr.GetValue().GetValue()); +vector> +PEGTransformerFactory::TransformValuesExpressions(PEGTransformer &transformer, + vector> expression) { + return expression; } } // namespace duckdb diff --git a/src/duckdb/src/parser/statement/explain_statement.cpp b/src/duckdb/src/parser/statement/explain_statement.cpp index 55c72b2b6..dc18e4296 100644 --- a/src/duckdb/src/parser/statement/explain_statement.cpp +++ b/src/duckdb/src/parser/statement/explain_statement.cpp @@ -4,14 +4,13 @@ namespace duckdb { ExplainStatement::ExplainStatement(unique_ptr stmt, ExplainType explain_type, - ExplainFormat explain_format) + const ProfilerPrintFormat &format) : SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(std::move(stmt)), explain_type(explain_type), - explain_format(explain_format) { + format(format) { } ExplainStatement::ExplainStatement(const ExplainStatement &other) - : SQLStatement(other), stmt(other.stmt->Copy()), explain_type(other.explain_type), - explain_format(other.explain_format) { + : SQLStatement(other), stmt(other.stmt->Copy()), explain_type(other.explain_type), format(other.format) { } unique_ptr ExplainStatement::Copy() const { @@ -24,13 +23,13 @@ string ExplainStatement::OptionsToString() const { options += "("; options += "ANALYZE"; } - if (explain_format != ExplainFormat::DEFAULT) { + if (format != ProfilerPrintFormat::Default()) { if (options.empty()) { options += "("; } else { options += ", "; } - options += StringUtil::Format("FORMAT %s", EnumUtil::ToString(explain_format)); + options += StringUtil::Format("FORMAT %s", StringUtil::Upper(format.ToString())); } if (!options.empty()) { options += ")"; diff --git a/src/duckdb/src/planner/binder/statement/bind_explain.cpp b/src/duckdb/src/planner/binder/statement/bind_explain.cpp index b223cf06f..1141d30ba 100644 --- a/src/duckdb/src/planner/binder/statement/bind_explain.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_explain.cpp @@ -10,8 +10,8 @@ BoundStatement Binder::Bind(ExplainStatement &stmt) { // bind the underlying statement auto plan = Bind(*stmt.stmt); // get the unoptimized logical plan, and create the explain statement - auto logical_plan_unopt = plan.plan->ToString(stmt.explain_format); - auto explain = make_uniq(std::move(plan.plan), stmt.explain_type, stmt.explain_format); + auto logical_plan_unopt = plan.plan->ToString(stmt.format); + auto explain = make_uniq(std::move(plan.plan), stmt.explain_type, stmt.format); explain->logical_plan_unopt = logical_plan_unopt; result.plan = std::move(explain); diff --git a/src/duckdb/src/planner/logical_operator.cpp b/src/duckdb/src/planner/logical_operator.cpp index 5f01308f8..3bb934da0 100644 --- a/src/duckdb/src/planner/logical_operator.cpp +++ b/src/duckdb/src/planner/logical_operator.cpp @@ -156,8 +156,12 @@ vector LogicalOperator::MapBindings(const vector & } } -string LogicalOperator::ToString(ExplainFormat format) const { +string LogicalOperator::ToString(const ProfilerPrintFormat &format) const { auto renderer = TreeRenderer::CreateRenderer(format); + if (!renderer) { + // formats without output (e.g. "no_output") render nothing + return string(); + } duckdb::stringstream ss; auto tree = RenderTree::CreateRenderTree(*this); renderer->ToStream(*tree, ss); diff --git a/src/duckdb/src/planner/operator/logical_explain.cpp b/src/duckdb/src/planner/operator/logical_explain.cpp index cd2873b69..9c771f906 100644 --- a/src/duckdb/src/planner/operator/logical_explain.cpp +++ b/src/duckdb/src/planner/operator/logical_explain.cpp @@ -2,9 +2,9 @@ namespace duckdb { -LogicalExplain::LogicalExplain(unique_ptr plan, ExplainType explain_type, ExplainFormat explain_format) - : LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN), explain_type(explain_type), - explain_format(explain_format) { +LogicalExplain::LogicalExplain(unique_ptr plan, ExplainType explain_type, + const ProfilerPrintFormat &format) + : LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN), explain_type(explain_type), format(format) { children.push_back(std::move(plan)); } diff --git a/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp b/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp index f6577271c..d487b8886 100644 --- a/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp +++ b/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp @@ -283,6 +283,37 @@ static bool PushEligibleFiltersIntoDelimJoinInputs(unique_ptr & return changed; } +static bool IsColumnEqualityPredicate(Expression &expr) { + if (!BoundComparisonExpression::IsComparison(expr)) { + return false; + } + switch (expr.GetExpressionType()) { + case ExpressionType::COMPARE_EQUAL: + case ExpressionType::COMPARE_NOT_DISTINCT_FROM: + break; + default: + return false; + } + auto &comparison = expr.Cast(); + auto &lhs = BoundComparisonExpression::Left(comparison); + auto &rhs = BoundComparisonExpression::Right(comparison); + if (lhs.GetExpressionType() != ExpressionType::BOUND_COLUMN_REF || + rhs.GetExpressionType() != ExpressionType::BOUND_COLUMN_REF) { + return false; + } + return lhs.Cast().Depth() == 0 && rhs.Cast().Depth() == 0; +} + +static bool IsNonSelectiveJoinPredicate(Expression &expr) { + if (expr.GetExpressionType() == ExpressionType::CONJUNCTION_AND) { + bool all_children_non_selective = true; + ExpressionIterator::EnumerateChildren( + expr, [&](Expression &child) { all_children_non_selective &= IsNonSelectiveJoinPredicate(child); }); + return all_children_non_selective; + } + return IsColumnEqualityPredicate(expr); +} + static bool HasSelection(const LogicalOperator &op) { switch (op.type) { case LogicalOperatorType::LOGICAL_GET: { @@ -298,8 +329,15 @@ static bool HasSelection(const LogicalOperator &op) { } break; } - case LogicalOperatorType::LOGICAL_FILTER: - return true; + case LogicalOperatorType::LOGICAL_FILTER: { + auto &filter = op.Cast(); + for (auto &expr : filter.expressions) { + if (!IsNonSelectiveJoinPredicate(*expr)) { + return true; + } + } + break; + } default: break; } diff --git a/src/duckdb/src/storage/data_table.cpp b/src/duckdb/src/storage/data_table.cpp index 6be939bbc..2863e3be7 100644 --- a/src/duckdb/src/storage/data_table.cpp +++ b/src/duckdb/src/storage/data_table.cpp @@ -14,7 +14,7 @@ #include "duckdb/execution/index/unbound_index.hpp" #include "duckdb/main/attached_database.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/profiling_utils.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/parser/constraints/list.hpp" #include "duckdb/planner/constraints/list.hpp" diff --git a/src/duckdb/src/storage/table/row_group_collection.cpp b/src/duckdb/src/storage/table/row_group_collection.cpp index 7b37aa6a5..70c5d2695 100644 --- a/src/duckdb/src/storage/table/row_group_collection.cpp +++ b/src/duckdb/src/storage/table/row_group_collection.cpp @@ -7,7 +7,7 @@ #include "duckdb/execution/index/art/art.hpp" #include "duckdb/execution/index/bound_index.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/profiling_utils.hpp" +#include "duckdb/main/profiler/profiling_utils.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/main/settings.hpp" #include "duckdb/parallel/task_executor.hpp" diff --git a/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp b/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp index 8cf8af345..1fdfd5cdb 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_algebraic.cpp @@ -1,8 +1,8 @@ #include "extension/core_functions/aggregate/algebraic/avg.cpp" -#include "extension/core_functions/aggregate/algebraic/corr.cpp" - #include "extension/core_functions/aggregate/algebraic/covar.cpp" #include "extension/core_functions/aggregate/algebraic/stddev.cpp" +#include "extension/core_functions/aggregate/algebraic/corr.cpp" + diff --git a/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp b/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp index dfecded9e..ffd7c8dad 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_distributive.cpp @@ -1,20 +1,20 @@ -#include "extension/core_functions/aggregate/distributive/bitagg.cpp" - #include "extension/core_functions/aggregate/distributive/approx_count.cpp" -#include "extension/core_functions/aggregate/distributive/bool.cpp" - #include "extension/core_functions/aggregate/distributive/arg_min_max.cpp" -#include "extension/core_functions/aggregate/distributive/string_agg.cpp" +#include "extension/core_functions/aggregate/distributive/product.cpp" -#include "extension/core_functions/aggregate/distributive/sum.cpp" +#include "extension/core_functions/aggregate/distributive/skew.cpp" #include "extension/core_functions/aggregate/distributive/kurtosis.cpp" -#include "extension/core_functions/aggregate/distributive/skew.cpp" +#include "extension/core_functions/aggregate/distributive/sum.cpp" + +#include "extension/core_functions/aggregate/distributive/bitagg.cpp" #include "extension/core_functions/aggregate/distributive/bitstring_agg.cpp" -#include "extension/core_functions/aggregate/distributive/product.cpp" +#include "extension/core_functions/aggregate/distributive/string_agg.cpp" + +#include "extension/core_functions/aggregate/distributive/bool.cpp" diff --git a/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp b/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp index d27f74f4f..4f892afa3 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_holistic.cpp @@ -1,9 +1,9 @@ +#include "extension/core_functions/aggregate/holistic/quantile.cpp" + #include "extension/core_functions/aggregate/holistic/mode.cpp" #include "extension/core_functions/aggregate/holistic/reservoir_quantile.cpp" -#include "extension/core_functions/aggregate/holistic/quantile.cpp" - #include "extension/core_functions/aggregate/holistic/approx_top_k.cpp" #include "extension/core_functions/aggregate/holistic/mad.cpp" diff --git a/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp b/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp index 0b4f57e9c..340382e4f 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_nested.cpp @@ -1,6 +1,6 @@ +#include "extension/core_functions/aggregate/nested/histogram.cpp" + #include "extension/core_functions/aggregate/nested/list.cpp" #include "extension/core_functions/aggregate/nested/binned_histogram.cpp" -#include "extension/core_functions/aggregate/nested/histogram.cpp" - diff --git a/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp b/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp index 4b5d14dc3..071bc16d4 100644 --- a/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp +++ b/src/duckdb/ub_extension_core_functions_aggregate_regression.cpp @@ -1,14 +1,14 @@ -#include "extension/core_functions/aggregate/regression/regr_sxx_syy.cpp" - -#include "extension/core_functions/aggregate/regression/regr_slope.cpp" - #include "extension/core_functions/aggregate/regression/regr_r2.cpp" #include "extension/core_functions/aggregate/regression/regr_avg.cpp" #include "extension/core_functions/aggregate/regression/regr_sxy.cpp" -#include "extension/core_functions/aggregate/regression/regr_intercept.cpp" +#include "extension/core_functions/aggregate/regression/regr_sxx_syy.cpp" + +#include "extension/core_functions/aggregate/regression/regr_slope.cpp" #include "extension/core_functions/aggregate/regression/regr_count.cpp" +#include "extension/core_functions/aggregate/regression/regr_intercept.cpp" + diff --git a/src/duckdb/ub_extension_core_functions_scalar_date.cpp b/src/duckdb/ub_extension_core_functions_scalar_date.cpp index 837ee7002..869059d9b 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_date.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_date.cpp @@ -1,20 +1,20 @@ -#include "extension/core_functions/scalar/date/date_diff.cpp" - #include "extension/core_functions/scalar/date/time_bucket.cpp" -#include "extension/core_functions/scalar/date/to_interval.cpp" +#include "extension/core_functions/scalar/date/current.cpp" -#include "extension/core_functions/scalar/date/date_part.cpp" +#include "extension/core_functions/scalar/date/date_sub.cpp" #include "extension/core_functions/scalar/date/make_date.cpp" -#include "extension/core_functions/scalar/date/epoch.cpp" +#include "extension/core_functions/scalar/date/age.cpp" -#include "extension/core_functions/scalar/date/date_sub.cpp" +#include "extension/core_functions/scalar/date/date_part.cpp" -#include "extension/core_functions/scalar/date/date_trunc.cpp" +#include "extension/core_functions/scalar/date/to_interval.cpp" -#include "extension/core_functions/scalar/date/current.cpp" +#include "extension/core_functions/scalar/date/epoch.cpp" -#include "extension/core_functions/scalar/date/age.cpp" +#include "extension/core_functions/scalar/date/date_trunc.cpp" + +#include "extension/core_functions/scalar/date/date_diff.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_debug.cpp b/src/duckdb/ub_extension_core_functions_scalar_debug.cpp index e452f015d..4ba1ce617 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_debug.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_debug.cpp @@ -1,6 +1,6 @@ -#include "extension/core_functions/scalar/debug/index_key.cpp" +#include "extension/core_functions/scalar/debug/sleep.cpp" #include "extension/core_functions/scalar/debug/vector_type.cpp" -#include "extension/core_functions/scalar/debug/sleep.cpp" +#include "extension/core_functions/scalar/debug/index_key.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_generic.cpp b/src/duckdb/ub_extension_core_functions_scalar_generic.cpp index c1a5ddd44..0242be3c2 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_generic.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_generic.cpp @@ -1,22 +1,22 @@ +#include "extension/core_functions/scalar/generic/binning.cpp" + #include "extension/core_functions/scalar/generic/system_functions.cpp" #include "extension/core_functions/scalar/generic/stats.cpp" -#include "extension/core_functions/scalar/generic/alias.cpp" - #include "extension/core_functions/scalar/generic/current_setting.cpp" -#include "extension/core_functions/scalar/generic/can_implicitly_cast.cpp" - -#include "extension/core_functions/scalar/generic/hash.cpp" +#include "extension/core_functions/scalar/generic/least.cpp" #include "extension/core_functions/scalar/generic/type_functions.cpp" -#include "extension/core_functions/scalar/generic/binning.cpp" +#include "extension/core_functions/scalar/generic/replace_type.cpp" -#include "extension/core_functions/scalar/generic/least.cpp" +#include "extension/core_functions/scalar/generic/can_implicitly_cast.cpp" #include "extension/core_functions/scalar/generic/cast_to_type.cpp" -#include "extension/core_functions/scalar/generic/replace_type.cpp" +#include "extension/core_functions/scalar/generic/alias.cpp" + +#include "extension/core_functions/scalar/generic/hash.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_list.cpp b/src/duckdb/ub_extension_core_functions_scalar_list.cpp index 8db8cd259..a0909eac1 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_list.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_list.cpp @@ -1,22 +1,22 @@ -#include "extension/core_functions/scalar/list/list_value.cpp" - -#include "extension/core_functions/scalar/list/list_transform.cpp" +#include "extension/core_functions/scalar/list/list_reduce.cpp" #include "extension/core_functions/scalar/list/flatten.cpp" #include "extension/core_functions/scalar/list/list_filter.cpp" -#include "extension/core_functions/scalar/list/range.cpp" +#include "extension/core_functions/scalar/list/list_value.cpp" #include "extension/core_functions/scalar/list/list_sort.cpp" -#include "extension/core_functions/scalar/list/array_slice.cpp" +#include "extension/core_functions/scalar/list/range.cpp" -#include "extension/core_functions/scalar/list/list_has_any_or_all.cpp" +#include "extension/core_functions/scalar/list/list_transform.cpp" -#include "extension/core_functions/scalar/list/list_reduce.cpp" +#include "extension/core_functions/scalar/list/list_distance.cpp" + +#include "extension/core_functions/scalar/list/list_has_any_or_all.cpp" #include "extension/core_functions/scalar/list/list_aggregates.cpp" -#include "extension/core_functions/scalar/list/list_distance.cpp" +#include "extension/core_functions/scalar/list/array_slice.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_map.cpp b/src/duckdb/ub_extension_core_functions_scalar_map.cpp index 4d1a1e38d..78538a430 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_map.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_map.cpp @@ -1,16 +1,16 @@ -#include "extension/core_functions/scalar/map/map_from_entries.cpp" - #include "extension/core_functions/scalar/map/switch.cpp" -#include "extension/core_functions/scalar/map/map_extract.cpp" - -#include "extension/core_functions/scalar/map/cardinality.cpp" - #include "extension/core_functions/scalar/map/map_entries.cpp" #include "extension/core_functions/scalar/map/map.cpp" #include "extension/core_functions/scalar/map/map_keys_values.cpp" +#include "extension/core_functions/scalar/map/cardinality.cpp" + #include "extension/core_functions/scalar/map/map_concat.cpp" +#include "extension/core_functions/scalar/map/map_extract.cpp" + +#include "extension/core_functions/scalar/map/map_from_entries.cpp" + diff --git a/src/duckdb/ub_extension_core_functions_scalar_string.cpp b/src/duckdb/ub_extension_core_functions_scalar_string.cpp index 3fbf16661..9da959101 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_string.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_string.cpp @@ -1,50 +1,50 @@ -#include "extension/core_functions/scalar/string/repeat.cpp" +#include "extension/core_functions/scalar/string/translate.cpp" -#include "extension/core_functions/scalar/string/parse_path.cpp" +#include "extension/core_functions/scalar/string/jaro_winkler.cpp" -#include "extension/core_functions/scalar/string/starts_with.cpp" +#include "extension/core_functions/scalar/string/parse_formatted_bytes.cpp" -#include "extension/core_functions/scalar/string/jaro_winkler.cpp" +#include "extension/core_functions/scalar/string/hamming.cpp" -#include "extension/core_functions/scalar/string/trim.cpp" +#include "extension/core_functions/scalar/string/unicode.cpp" -#include "extension/core_functions/scalar/string/format_bytes.cpp" +#include "extension/core_functions/scalar/string/chr.cpp" -#include "extension/core_functions/scalar/string/pad.cpp" +#include "extension/core_functions/scalar/string/format_bytes.cpp" -#include "extension/core_functions/scalar/string/to_base.cpp" +#include "extension/core_functions/scalar/string/reverse.cpp" -#include "extension/core_functions/scalar/string/bar.cpp" +#include "extension/core_functions/scalar/string/hex.cpp" -#include "extension/core_functions/scalar/string/translate.cpp" +#include "extension/core_functions/scalar/string/instr.cpp" -#include "extension/core_functions/scalar/string/url_encode.cpp" +#include "extension/core_functions/scalar/string/parse_path.cpp" -#include "extension/core_functions/scalar/string/left_right.cpp" +#include "extension/core_functions/scalar/string/starts_with.cpp" -#include "extension/core_functions/scalar/string/reverse.cpp" +#include "extension/core_functions/scalar/string/to_base.cpp" #include "extension/core_functions/scalar/string/ascii.cpp" -#include "extension/core_functions/scalar/string/printf.cpp" - -#include "extension/core_functions/scalar/string/replace.cpp" +#include "extension/core_functions/scalar/string/repeat.cpp" -#include "extension/core_functions/scalar/string/chr.cpp" +#include "extension/core_functions/scalar/string/url_encode.cpp" #include "extension/core_functions/scalar/string/jaccard.cpp" -#include "extension/core_functions/scalar/string/hex.cpp" +#include "extension/core_functions/scalar/string/levenshtein.cpp" -#include "extension/core_functions/scalar/string/hamming.cpp" +#include "extension/core_functions/scalar/string/damerau_levenshtein.cpp" -#include "extension/core_functions/scalar/string/levenshtein.cpp" +#include "extension/core_functions/scalar/string/replace.cpp" -#include "extension/core_functions/scalar/string/instr.cpp" +#include "extension/core_functions/scalar/string/printf.cpp" -#include "extension/core_functions/scalar/string/unicode.cpp" +#include "extension/core_functions/scalar/string/left_right.cpp" -#include "extension/core_functions/scalar/string/parse_formatted_bytes.cpp" +#include "extension/core_functions/scalar/string/pad.cpp" -#include "extension/core_functions/scalar/string/damerau_levenshtein.cpp" +#include "extension/core_functions/scalar/string/trim.cpp" + +#include "extension/core_functions/scalar/string/bar.cpp" diff --git a/src/duckdb/ub_extension_core_functions_scalar_struct.cpp b/src/duckdb/ub_extension_core_functions_scalar_struct.cpp index 56181b4e4..7cc473ffb 100644 --- a/src/duckdb/ub_extension_core_functions_scalar_struct.cpp +++ b/src/duckdb/ub_extension_core_functions_scalar_struct.cpp @@ -1,8 +1,8 @@ -#include "extension/core_functions/scalar/struct/struct_values.cpp" - #include "extension/core_functions/scalar/struct/struct_insert.cpp" -#include "extension/core_functions/scalar/struct/struct_keys.cpp" +#include "extension/core_functions/scalar/struct/struct_values.cpp" #include "extension/core_functions/scalar/struct/struct_update.cpp" +#include "extension/core_functions/scalar/struct/struct_keys.cpp" + diff --git a/src/duckdb/ub_extension_icu_third_party_icu_common.cpp b/src/duckdb/ub_extension_icu_third_party_icu_common.cpp index d6cb3c42c..4a230511f 100644 --- a/src/duckdb/ub_extension_icu_third_party_icu_common.cpp +++ b/src/duckdb/ub_extension_icu_third_party_icu_common.cpp @@ -1,222 +1,222 @@ -#include "extension/icu/third_party/icu/common/uset_props.cpp" +#include "extension/icu/third_party/icu/common/uniset_props.cpp" -#include "extension/icu/third_party/icu/common/ustring.cpp" +#include "extension/icu/third_party/icu/common/propname.cpp" -#include "extension/icu/third_party/icu/common/caniter.cpp" +#include "extension/icu/third_party/icu/common/unorm.cpp" + +#include "extension/icu/third_party/icu/common/normalizer2.cpp" + +#include "extension/icu/third_party/icu/common/dtintrv.cpp" + +#include "extension/icu/third_party/icu/common/loclikely.cpp" #include "extension/icu/third_party/icu/common/cstr.cpp" -#include "extension/icu/third_party/icu/common/ubidiln.cpp" +#include "extension/icu/third_party/icu/common/stringpiece.cpp" -#include "extension/icu/third_party/icu/common/utf_impl.cpp" +#include "extension/icu/third_party/icu/common/ustring.cpp" -#include "extension/icu/third_party/icu/common/uniset_props.cpp" +#include "extension/icu/third_party/icu/common/cmemory.cpp" -#include "extension/icu/third_party/icu/common/patternprops.cpp" +#include "extension/icu/third_party/icu/common/uvectr32.cpp" -#include "extension/icu/third_party/icu/common/ushape.cpp" +#include "extension/icu/third_party/icu/common/ucurr.cpp" #include "extension/icu/third_party/icu/common/bytestream.cpp" -#include "extension/icu/third_party/icu/common/characterproperties.cpp" +#include "extension/icu/third_party/icu/common/appendable.cpp" #include "extension/icu/third_party/icu/common/locavailable.cpp" -#include "extension/icu/third_party/icu/common/locid.cpp" +#include "extension/icu/third_party/icu/common/utypes.cpp" -#include "extension/icu/third_party/icu/common/simpleformatter.cpp" +#include "extension/icu/third_party/icu/common/utrie_swap.cpp" -#include "extension/icu/third_party/icu/common/uchar.cpp" +#include "extension/icu/third_party/icu/common/schriter.cpp" -#include "extension/icu/third_party/icu/common/ucmndata.cpp" +#include "extension/icu/third_party/icu/common/utext.cpp" -#include "extension/icu/third_party/icu/common/propname.cpp" +#include "extension/icu/third_party/icu/common/unistr.cpp" -#include "extension/icu/third_party/icu/common/uprops.cpp" +#include "extension/icu/third_party/icu/common/uloc_keytype.cpp" -#include "extension/icu/third_party/icu/common/locresdata.cpp" +#include "extension/icu/third_party/icu/common/ustrtrns.cpp" -#include "extension/icu/third_party/icu/common/ruleiter.cpp" +#include "extension/icu/third_party/icu/common/uniset.cpp" #include "extension/icu/third_party/icu/common/uobject.cpp" -#include "extension/icu/third_party/icu/common/ustack.cpp" - -#include "extension/icu/third_party/icu/common/filterednormalizer2.cpp" - -#include "extension/icu/third_party/icu/common/usc_impl.cpp" +#include "extension/icu/third_party/icu/common/umutex.cpp" -#include "extension/icu/third_party/icu/common/resbund.cpp" +#include "extension/icu/third_party/icu/common/unistr_case_locale.cpp" -#include "extension/icu/third_party/icu/common/util_props.cpp" +#include "extension/icu/third_party/icu/common/ulist.cpp" -#include "extension/icu/third_party/icu/common/locbased.cpp" +#include "extension/icu/third_party/icu/common/uarrsort.cpp" -#include "extension/icu/third_party/icu/common/resource.cpp" +#include "extension/icu/third_party/icu/common/ustack.cpp" -#include "extension/icu/third_party/icu/common/uchriter.cpp" +#include "extension/icu/third_party/icu/common/characterproperties.cpp" -#include "extension/icu/third_party/icu/common/usetiter.cpp" +#include "extension/icu/third_party/icu/common/ubidiln.cpp" -#include "extension/icu/third_party/icu/common/edits.cpp" +#include "extension/icu/third_party/icu/common/udataswp.cpp" -#include "extension/icu/third_party/icu/common/ucasemap.cpp" +#include "extension/icu/third_party/icu/common/locdispnames.cpp" -#include "extension/icu/third_party/icu/common/stringtriebuilder.cpp" +#include "extension/icu/third_party/icu/common/unisetspan.cpp" -#include "extension/icu/third_party/icu/common/normlzr.cpp" +#include "extension/icu/third_party/icu/common/uinvchar.cpp" -#include "extension/icu/third_party/icu/common/ustr_wcs.cpp" +#include "extension/icu/third_party/icu/common/ucln_cmn.cpp" -#include "extension/icu/third_party/icu/common/util.cpp" +#include "extension/icu/third_party/icu/common/uinit.cpp" -#include "extension/icu/third_party/icu/common/uvectr64.cpp" +#include "extension/icu/third_party/icu/common/localeprioritylist.cpp" -#include "extension/icu/third_party/icu/common/appendable.cpp" +#include "extension/icu/third_party/icu/common/unifilt.cpp" -#include "extension/icu/third_party/icu/common/pluralmap.cpp" +#include "extension/icu/third_party/icu/common/ubidiwrt.cpp" -#include "extension/icu/third_party/icu/common/ustrtrns.cpp" +#include "extension/icu/third_party/icu/common/fixedstring.cpp" -#include "extension/icu/third_party/icu/common/ulist.cpp" +#include "extension/icu/third_party/icu/common/umath.cpp" -#include "extension/icu/third_party/icu/common/uloc_tag.cpp" +#include "extension/icu/third_party/icu/common/uenum.cpp" -#include "extension/icu/third_party/icu/common/utrace.cpp" +#include "extension/icu/third_party/icu/common/uset_props.cpp" -#include "extension/icu/third_party/icu/common/ubidiwrt.cpp" +#include "extension/icu/third_party/icu/common/unifunct.cpp" -#include "extension/icu/third_party/icu/common/messagepattern.cpp" +#include "extension/icu/third_party/icu/common/errorcode.cpp" -#include "extension/icu/third_party/icu/common/ucln_cmn.cpp" +#include "extension/icu/third_party/icu/common/uloc_tag.cpp" -#include "extension/icu/third_party/icu/common/chariter.cpp" +#include "extension/icu/third_party/icu/common/ustrenum.cpp" -#include "extension/icu/third_party/icu/common/uarrsort.cpp" +#include "extension/icu/third_party/icu/common/parsepos.cpp" -#include "extension/icu/third_party/icu/common/loclikely.cpp" +#include "extension/icu/third_party/icu/common/uset.cpp" -#include "extension/icu/third_party/icu/common/unorm.cpp" +#include "extension/icu/third_party/icu/common/cstring.cpp" -#include "extension/icu/third_party/icu/common/uinit.cpp" +#include "extension/icu/third_party/icu/common/ucasemap.cpp" -#include "extension/icu/third_party/icu/common/propsvec.cpp" +#include "extension/icu/third_party/icu/common/uiter.cpp" -#include "extension/icu/third_party/icu/common/resbund_cnv.cpp" +#include "extension/icu/third_party/icu/common/lsr.cpp" -#include "extension/icu/third_party/icu/common/sharedobject.cpp" +#include "extension/icu/third_party/icu/common/edits.cpp" -#include "extension/icu/third_party/icu/common/utrie_swap.cpp" +#include "extension/icu/third_party/icu/common/emojiprops.cpp" -#include "extension/icu/third_party/icu/common/ucharstrie.cpp" +#include "extension/icu/third_party/icu/common/stringtriebuilder.cpp" -#include "extension/icu/third_party/icu/common/uvectr32.cpp" +#include "extension/icu/third_party/icu/common/uvectr64.cpp" -#include "extension/icu/third_party/icu/common/stringpiece.cpp" +#include "extension/icu/third_party/icu/common/resbund.cpp" -#include "extension/icu/third_party/icu/common/unistr_props.cpp" +#include "extension/icu/third_party/icu/common/ucharstrie.cpp" -#include "extension/icu/third_party/icu/common/charstr.cpp" +#include "extension/icu/third_party/icu/common/filterednormalizer2.cpp" -#include "extension/icu/third_party/icu/common/lsr.cpp" +#include "extension/icu/third_party/icu/common/uchar.cpp" -#include "extension/icu/third_party/icu/common/umath.cpp" +#include "extension/icu/third_party/icu/common/chariter.cpp" -#include "extension/icu/third_party/icu/common/dtintrv.cpp" +#include "extension/icu/third_party/icu/common/locid.cpp" -#include "extension/icu/third_party/icu/common/locdispnames.cpp" +#include "extension/icu/third_party/icu/common/ustrcase_locale.cpp" -#include "extension/icu/third_party/icu/common/ucat.cpp" +#include "extension/icu/third_party/icu/common/unistr_case.cpp" -#include "extension/icu/third_party/icu/common/uscript.cpp" +#include "extension/icu/third_party/icu/common/sharedobject.cpp" -#include "extension/icu/third_party/icu/common/fixedstring.cpp" +#include "extension/icu/third_party/icu/common/simpleformatter.cpp" -#include "extension/icu/third_party/icu/common/umutex.cpp" +#include "extension/icu/third_party/icu/common/util.cpp" #include "extension/icu/third_party/icu/common/normalizer2impl.cpp" -#include "extension/icu/third_party/icu/common/udatamem.cpp" +#include "extension/icu/third_party/icu/common/uprops.cpp" -#include "extension/icu/third_party/icu/common/unistr_case_locale.cpp" +#include "extension/icu/third_party/icu/common/patternprops.cpp" -#include "extension/icu/third_party/icu/common/bytesinkutil.cpp" +#include "extension/icu/third_party/icu/common/locdspnm.cpp" -#include "extension/icu/third_party/icu/common/bytestrie.cpp" +#include "extension/icu/third_party/icu/common/ucharstrieiterator.cpp" -#include "extension/icu/third_party/icu/common/udata.cpp" +#include "extension/icu/third_party/icu/common/messagepattern.cpp" -#include "extension/icu/third_party/icu/common/cstring.cpp" +#include "extension/icu/third_party/icu/common/bytestrie.cpp" -#include "extension/icu/third_party/icu/common/utext.cpp" +#include "extension/icu/third_party/icu/common/uscript.cpp" -#include "extension/icu/third_party/icu/common/uniset.cpp" +#include "extension/icu/third_party/icu/common/utf_impl.cpp" -#include "extension/icu/third_party/icu/common/localeprioritylist.cpp" +#include "extension/icu/third_party/icu/common/uniset_closure.cpp" -#include "extension/icu/third_party/icu/common/icudataver.cpp" +#include "extension/icu/third_party/icu/common/bmpset.cpp" -#include "extension/icu/third_party/icu/common/ubidi.cpp" +#include "extension/icu/third_party/icu/common/pluralmap.cpp" -#include "extension/icu/third_party/icu/common/uiter.cpp" +#include "extension/icu/third_party/icu/common/ucat.cpp" -#include "extension/icu/third_party/icu/common/parsepos.cpp" +#include "extension/icu/third_party/icu/common/udata.cpp" -#include "extension/icu/third_party/icu/common/unistr_case.cpp" +#include "extension/icu/third_party/icu/common/normlzr.cpp" -#include "extension/icu/third_party/icu/common/uenum.cpp" +#include "extension/icu/third_party/icu/common/ustr_wcs.cpp" -#include "extension/icu/third_party/icu/common/uloc_keytype.cpp" +#include "extension/icu/third_party/icu/common/locbased.cpp" -#include "extension/icu/third_party/icu/common/uhash_us.cpp" +#include "extension/icu/third_party/icu/common/usetiter.cpp" #include "extension/icu/third_party/icu/common/localematcher.cpp" -#include "extension/icu/third_party/icu/common/ucol_swp.cpp" - -#include "extension/icu/third_party/icu/common/ustrfmt.cpp" +#include "extension/icu/third_party/icu/common/charstr.cpp" -#include "extension/icu/third_party/icu/common/bytestrieiterator.cpp" +#include "extension/icu/third_party/icu/common/bytesinkutil.cpp" -#include "extension/icu/third_party/icu/common/ucharstrieiterator.cpp" +#include "extension/icu/third_party/icu/common/resbund_cnv.cpp" -#include "extension/icu/third_party/icu/common/unifilt.cpp" +#include "extension/icu/third_party/icu/common/bytestrieiterator.cpp" -#include "extension/icu/third_party/icu/common/uinvchar.cpp" +#include "extension/icu/third_party/icu/common/icudataver.cpp" -#include "extension/icu/third_party/icu/common/schriter.cpp" +#include "extension/icu/third_party/icu/common/resource.cpp" -#include "extension/icu/third_party/icu/common/uniset_closure.cpp" +#include "extension/icu/third_party/icu/common/ucol_swp.cpp" -#include "extension/icu/third_party/icu/common/cmemory.cpp" +#include "extension/icu/third_party/icu/common/ruleiter.cpp" -#include "extension/icu/third_party/icu/common/utypes.cpp" +#include "extension/icu/third_party/icu/common/udatamem.cpp" -#include "extension/icu/third_party/icu/common/ustrenum.cpp" +#include "extension/icu/third_party/icu/common/ures_cnv.cpp" -#include "extension/icu/third_party/icu/common/ustrcase_locale.cpp" +#include "extension/icu/third_party/icu/common/ushape.cpp" -#include "extension/icu/third_party/icu/common/ures_cnv.cpp" +#include "extension/icu/third_party/icu/common/propsvec.cpp" -#include "extension/icu/third_party/icu/common/normalizer2.cpp" +#include "extension/icu/third_party/icu/common/usc_impl.cpp" -#include "extension/icu/third_party/icu/common/unisetspan.cpp" +#include "extension/icu/third_party/icu/common/util_props.cpp" -#include "extension/icu/third_party/icu/common/uset.cpp" +#include "extension/icu/third_party/icu/common/uhash_us.cpp" -#include "extension/icu/third_party/icu/common/ucurr.cpp" +#include "extension/icu/third_party/icu/common/unistr_props.cpp" -#include "extension/icu/third_party/icu/common/locdspnm.cpp" +#include "extension/icu/third_party/icu/common/ucmndata.cpp" -#include "extension/icu/third_party/icu/common/unifunct.cpp" +#include "extension/icu/third_party/icu/common/ustrfmt.cpp" -#include "extension/icu/third_party/icu/common/udataswp.cpp" +#include "extension/icu/third_party/icu/common/uchriter.cpp" -#include "extension/icu/third_party/icu/common/bmpset.cpp" +#include "extension/icu/third_party/icu/common/caniter.cpp" -#include "extension/icu/third_party/icu/common/errorcode.cpp" +#include "extension/icu/third_party/icu/common/locresdata.cpp" -#include "extension/icu/third_party/icu/common/emojiprops.cpp" +#include "extension/icu/third_party/icu/common/utrace.cpp" -#include "extension/icu/third_party/icu/common/unistr.cpp" +#include "extension/icu/third_party/icu/common/ubidi.cpp" diff --git a/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp b/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp index 4a3d5f324..8171e1d4a 100644 --- a/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +++ b/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp @@ -1,182 +1,182 @@ -#include "extension/icu/third_party/icu/i18n/tznames_impl.cpp" +#include "extension/icu/third_party/icu/i18n/tztrans.cpp" -#include "extension/icu/third_party/icu/i18n/ucal.cpp" +#include "extension/icu/third_party/icu/i18n/collationruleparser.cpp" -#include "extension/icu/third_party/icu/i18n/zonemeta.cpp" +#include "extension/icu/third_party/icu/i18n/basictz.cpp" -#include "extension/icu/third_party/icu/i18n/ucol_sit.cpp" +#include "extension/icu/third_party/icu/i18n/utmscale.cpp" -#include "extension/icu/third_party/icu/i18n/collationtailoring.cpp" +#include "extension/icu/third_party/icu/i18n/tzrule.cpp" -#include "extension/icu/third_party/icu/i18n/dcfmtsym.cpp" +#include "extension/icu/third_party/icu/i18n/listformatter.cpp" #include "extension/icu/third_party/icu/i18n/coleitr.cpp" -#include "extension/icu/third_party/icu/i18n/units_converter.cpp" +#include "extension/icu/third_party/icu/i18n/collationdata.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatareader.cpp" +#include "extension/icu/third_party/icu/i18n/ucoleitr.cpp" -#include "extension/icu/third_party/icu/i18n/measunit.cpp" +#include "extension/icu/third_party/icu/i18n/sortkey.cpp" -#include "extension/icu/third_party/icu/i18n/ztrans.cpp" +#include "extension/icu/third_party/icu/i18n/dangical.cpp" -#include "extension/icu/third_party/icu/i18n/number_affixutils.cpp" +#include "extension/icu/third_party/icu/i18n/uregion.cpp" -#include "extension/icu/third_party/icu/i18n/tznames.cpp" +#include "extension/icu/third_party/icu/i18n/udateintervalformat.cpp" -#include "extension/icu/third_party/icu/i18n/udatpg.cpp" +#include "extension/icu/third_party/icu/i18n/ucln_in.cpp" #include "extension/icu/third_party/icu/i18n/formattedval_iterimpl.cpp" -#include "extension/icu/third_party/icu/i18n/ufieldpositer.cpp" - -#include "extension/icu/third_party/icu/i18n/collationfastlatin.cpp" +#include "extension/icu/third_party/icu/i18n/collationsettings.cpp" -#include "extension/icu/third_party/icu/i18n/tzfmt.cpp" +#include "extension/icu/third_party/icu/i18n/rbtz.cpp" -#include "extension/icu/third_party/icu/i18n/udateintervalformat.cpp" +#include "extension/icu/third_party/icu/i18n/collationtailoring.cpp" -#include "extension/icu/third_party/icu/i18n/fphdlimp.cpp" +#include "extension/icu/third_party/icu/i18n/tznames_impl.cpp" -#include "extension/icu/third_party/icu/i18n/sortkey.cpp" +#include "extension/icu/third_party/icu/i18n/currunit.cpp" -#include "extension/icu/third_party/icu/i18n/unum.cpp" +#include "extension/icu/third_party/icu/i18n/region.cpp" -#include "extension/icu/third_party/icu/i18n/collationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/ulocdata.cpp" -#include "extension/icu/third_party/icu/i18n/formatted_string_builder.cpp" +#include "extension/icu/third_party/icu/i18n/format.cpp" -#include "extension/icu/third_party/icu/i18n/collationfastlatinbuilder.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatawriter.cpp" -#include "extension/icu/third_party/icu/i18n/astro.cpp" +#include "extension/icu/third_party/icu/i18n/collationkeys.cpp" -#include "extension/icu/third_party/icu/i18n/region.cpp" +#include "extension/icu/third_party/icu/i18n/formattedvalue.cpp" -#include "extension/icu/third_party/icu/i18n/tmutamt.cpp" +#include "extension/icu/third_party/icu/i18n/decContext.cpp" -#include "extension/icu/third_party/icu/i18n/udat.cpp" +#include "extension/icu/third_party/icu/i18n/reldtfmt.cpp" -#include "extension/icu/third_party/icu/i18n/displayoptions.cpp" +#include "extension/icu/third_party/icu/i18n/standardplural.cpp" -#include "extension/icu/third_party/icu/i18n/uregion.cpp" +#include "extension/icu/third_party/icu/i18n/alphaindex.cpp" -#include "extension/icu/third_party/icu/i18n/listformatter.cpp" +#include "extension/icu/third_party/icu/i18n/datefmt.cpp" -#include "extension/icu/third_party/icu/i18n/rulebasedcollator.cpp" +#include "extension/icu/third_party/icu/i18n/uitercollationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/collationbuilder.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatareader.cpp" -#include "extension/icu/third_party/icu/i18n/vzone.cpp" +#include "extension/icu/third_party/icu/i18n/number_notation.cpp" -#include "extension/icu/third_party/icu/i18n/simpletz.cpp" +#include "extension/icu/third_party/icu/i18n/dtrule.cpp" -#include "extension/icu/third_party/icu/i18n/utf16collationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/unum.cpp" -#include "extension/icu/third_party/icu/i18n/reldtfmt.cpp" +#include "extension/icu/third_party/icu/i18n/ulistformatter.cpp" -#include "extension/icu/third_party/icu/i18n/unumsys.cpp" +#include "extension/icu/third_party/icu/i18n/tmutamt.cpp" -#include "extension/icu/third_party/icu/i18n/uitercollationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/bocsu.cpp" -#include "extension/icu/third_party/icu/i18n/collation.cpp" +#include "extension/icu/third_party/icu/i18n/utf16collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/rbtz.cpp" +#include "extension/icu/third_party/icu/i18n/tmunit.cpp" -#include "extension/icu/third_party/icu/i18n/erarules.cpp" +#include "extension/icu/third_party/icu/i18n/fpositer.cpp" -#include "extension/icu/third_party/icu/i18n/olsontz.cpp" +#include "extension/icu/third_party/icu/i18n/collationfastlatinbuilder.cpp" -#include "extension/icu/third_party/icu/i18n/ulistformatter.cpp" +#include "extension/icu/third_party/icu/i18n/number_modifiers.cpp" -#include "extension/icu/third_party/icu/i18n/formattedvalue.cpp" +#include "extension/icu/third_party/icu/i18n/collationcompare.cpp" -#include "extension/icu/third_party/icu/i18n/collationdata.cpp" +#include "extension/icu/third_party/icu/i18n/measunit.cpp" -#include "extension/icu/third_party/icu/i18n/bocsu.cpp" +#include "extension/icu/third_party/icu/i18n/astro.cpp" -#include "extension/icu/third_party/icu/i18n/fpositer.cpp" +#include "extension/icu/third_party/icu/i18n/udat.cpp" -#include "extension/icu/third_party/icu/i18n/currunit.cpp" +#include "extension/icu/third_party/icu/i18n/utf8collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/decContext.cpp" +#include "extension/icu/third_party/icu/i18n/selfmt.cpp" -#include "extension/icu/third_party/icu/i18n/collationsets.cpp" +#include "extension/icu/third_party/icu/i18n/collationiterator.cpp" -#include "extension/icu/third_party/icu/i18n/measure.cpp" +#include "extension/icu/third_party/icu/i18n/tzfmt.cpp" -#include "extension/icu/third_party/icu/i18n/format.cpp" +#include "extension/icu/third_party/icu/i18n/units_converter.cpp" -#include "extension/icu/third_party/icu/i18n/number_padding.cpp" +#include "extension/icu/third_party/icu/i18n/rulebasedcollator.cpp" -#include "extension/icu/third_party/icu/i18n/alphaindex.cpp" +#include "extension/icu/third_party/icu/i18n/dcfmtsym.cpp" -#include "extension/icu/third_party/icu/i18n/basictz.cpp" +#include "extension/icu/third_party/icu/i18n/dtitvinf.cpp" -#include "extension/icu/third_party/icu/i18n/umsg.cpp" +#include "extension/icu/third_party/icu/i18n/collationfcd.cpp" -#include "extension/icu/third_party/icu/i18n/dtrule.cpp" +#include "extension/icu/third_party/icu/i18n/udatpg.cpp" -#include "extension/icu/third_party/icu/i18n/collationfcd.cpp" +#include "extension/icu/third_party/icu/i18n/scientificnumberformatter.cpp" -#include "extension/icu/third_party/icu/i18n/number_notation.cpp" +#include "extension/icu/third_party/icu/i18n/coll.cpp" -#include "extension/icu/third_party/icu/i18n/ucln_in.cpp" +#include "extension/icu/third_party/icu/i18n/unumsys.cpp" -#include "extension/icu/third_party/icu/i18n/tzrule.cpp" +#include "extension/icu/third_party/icu/i18n/displayoptions.cpp" #include "extension/icu/third_party/icu/i18n/smpdtfst.cpp" -#include "extension/icu/third_party/icu/i18n/ulocdata.cpp" +#include "extension/icu/third_party/icu/i18n/zrule.cpp" -#include "extension/icu/third_party/icu/i18n/collationruleparser.cpp" +#include "extension/icu/third_party/icu/i18n/collationbuilder.cpp" -#include "extension/icu/third_party/icu/i18n/scientificnumberformatter.cpp" +#include "extension/icu/third_party/icu/i18n/vzone.cpp" -#include "extension/icu/third_party/icu/i18n/utf8collationiterator.cpp" +#include "extension/icu/third_party/icu/i18n/ufieldpositer.cpp" -#include "extension/icu/third_party/icu/i18n/tztrans.cpp" +#include "extension/icu/third_party/icu/i18n/ucol_sit.cpp" -#include "extension/icu/third_party/icu/i18n/zrule.cpp" +#include "extension/icu/third_party/icu/i18n/collationdatabuilder.cpp" + +#include "extension/icu/third_party/icu/i18n/collationfastlatin.cpp" + +#include "extension/icu/third_party/icu/i18n/number_padding.cpp" + +#include "extension/icu/third_party/icu/i18n/erarules.cpp" #include "extension/icu/third_party/icu/i18n/collationweights.cpp" -#include "extension/icu/third_party/icu/i18n/number_modifiers.cpp" +#include "extension/icu/third_party/icu/i18n/collationrootelements.cpp" -#include "extension/icu/third_party/icu/i18n/tmunit.cpp" +#include "extension/icu/third_party/icu/i18n/measure.cpp" -#include "extension/icu/third_party/icu/i18n/dtitvinf.cpp" +#include "extension/icu/third_party/icu/i18n/collationsets.cpp" -#include "extension/icu/third_party/icu/i18n/collationcompare.cpp" +#include "extension/icu/third_party/icu/i18n/ucal.cpp" -#include "extension/icu/third_party/icu/i18n/currfmt.cpp" +#include "extension/icu/third_party/icu/i18n/number_decimfmtprops.cpp" -#include "extension/icu/third_party/icu/i18n/selfmt.cpp" +#include "extension/icu/third_party/icu/i18n/umsg.cpp" -#include "extension/icu/third_party/icu/i18n/standardplural.cpp" +#include "extension/icu/third_party/icu/i18n/tznames.cpp" #include "extension/icu/third_party/icu/i18n/curramt.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatawriter.cpp" +#include "extension/icu/third_party/icu/i18n/simpletz.cpp" -#include "extension/icu/third_party/icu/i18n/ucoleitr.cpp" +#include "extension/icu/third_party/icu/i18n/number_affixutils.cpp" -#include "extension/icu/third_party/icu/i18n/number_decimfmtprops.cpp" +#include "extension/icu/third_party/icu/i18n/zonemeta.cpp" -#include "extension/icu/third_party/icu/i18n/collationdatabuilder.cpp" +#include "extension/icu/third_party/icu/i18n/olsontz.cpp" -#include "extension/icu/third_party/icu/i18n/datefmt.cpp" +#include "extension/icu/third_party/icu/i18n/ztrans.cpp" -#include "extension/icu/third_party/icu/i18n/utmscale.cpp" +#include "extension/icu/third_party/icu/i18n/fphdlimp.cpp" #include "extension/icu/third_party/icu/i18n/gender.cpp" -#include "extension/icu/third_party/icu/i18n/collationkeys.cpp" - -#include "extension/icu/third_party/icu/i18n/dangical.cpp" - -#include "extension/icu/third_party/icu/i18n/collationrootelements.cpp" +#include "extension/icu/third_party/icu/i18n/currfmt.cpp" -#include "extension/icu/third_party/icu/i18n/coll.cpp" +#include "extension/icu/third_party/icu/i18n/formatted_string_builder.cpp" -#include "extension/icu/third_party/icu/i18n/collationsettings.cpp" +#include "extension/icu/third_party/icu/i18n/collation.cpp" diff --git a/src/duckdb/ub_extension_json_json_functions.cpp b/src/duckdb/ub_extension_json_json_functions.cpp index d4615dc86..1523a5983 100644 --- a/src/duckdb/ub_extension_json_json_functions.cpp +++ b/src/duckdb/ub_extension_json_json_functions.cpp @@ -1,46 +1,46 @@ -#include "extension/json/json_functions/json_valid.cpp" +#include "extension/json/json_functions/json_contains.cpp" #include "extension/json/json_functions/read_json.cpp" -#include "extension/json/json_functions/json_transform.cpp" - #include "extension/json/json_functions/json_extract.cpp" -#include "extension/json/json_functions/json_exists.cpp" +#include "extension/json/json_functions/json_type.cpp" -#include "extension/json/json_functions/json_merge_patch_diff.cpp" +#include "extension/json/json_functions/json_valid.cpp" -#include "extension/json/json_functions/json_serialize_sql.cpp" +#include "extension/json/json_functions/json_transform.cpp" -#include "extension/json/json_functions/json_serialize_plan.cpp" +#include "extension/json/json_functions/json_keys.cpp" -#include "extension/json/json_functions/json_pretty.cpp" +#include "extension/json/json_functions/copy_json.cpp" -#include "extension/json/json_functions/json_contains.cpp" +#include "extension/json/json_functions/json_table_in_out.cpp" -#include "extension/json/json_functions/json_type.cpp" +#include "extension/json/json_functions/json_serialize_plan.cpp" -#include "extension/json/json_functions/copy_json.cpp" +#include "extension/json/json_functions/json_strip_nulls.cpp" -#include "extension/json/json_functions/json_table_in_out.cpp" +#include "extension/json/json_functions/json_merge_patch_diff.cpp" -#include "extension/json/json_functions/json_value.cpp" +#include "extension/json/json_functions/json_exists.cpp" -#include "extension/json/json_functions/json_array_length.cpp" +#include "extension/json/json_functions/json_structure.cpp" -#include "extension/json/json_functions/json_normalize.cpp" +#include "extension/json/json_functions/json_pretty.cpp" + +#include "extension/json/json_functions/read_json_objects.cpp" #include "extension/json/json_functions/json_create.cpp" #include "extension/json/json_functions/json_deep_merge.cpp" -#include "extension/json/json_functions/json_structure.cpp" +#include "extension/json/json_functions/json_serialize_sql.cpp" -#include "extension/json/json_functions/read_json_objects.cpp" +#include "extension/json/json_functions/json_value.cpp" -#include "extension/json/json_functions/json_strip_nulls.cpp" +#include "extension/json/json_functions/json_array_length.cpp" -#include "extension/json/json_functions/json_merge_patch.cpp" +#include "extension/json/json_functions/json_normalize.cpp" -#include "extension/json/json_functions/json_keys.cpp" +#include "extension/json/json_functions/json_merge_patch.cpp" diff --git a/src/duckdb/ub_extension_parquet_decoder.cpp b/src/duckdb/ub_extension_parquet_decoder.cpp index 997d85451..5d625aaf8 100644 --- a/src/duckdb/ub_extension_parquet_decoder.cpp +++ b/src/duckdb/ub_extension_parquet_decoder.cpp @@ -1,6 +1,4 @@ -#include "extension/parquet/decoder/delta_byte_array_decoder.cpp" - -#include "extension/parquet/decoder/delta_binary_packed_decoder.cpp" +#include "extension/parquet/decoder/rle_decoder.cpp" #include "extension/parquet/decoder/dictionary_decoder.cpp" @@ -8,5 +6,7 @@ #include "extension/parquet/decoder/byte_stream_split_decoder.cpp" -#include "extension/parquet/decoder/rle_decoder.cpp" +#include "extension/parquet/decoder/delta_binary_packed_decoder.cpp" + +#include "extension/parquet/decoder/delta_byte_array_decoder.cpp" diff --git a/src/duckdb/ub_extension_parquet_reader.cpp b/src/duckdb/ub_extension_parquet_reader.cpp index 2a440cbb8..28b599256 100644 --- a/src/duckdb/ub_extension_parquet_reader.cpp +++ b/src/duckdb/ub_extension_parquet_reader.cpp @@ -1,14 +1,14 @@ -#include "extension/parquet/reader/string_column_reader.cpp" - -#include "extension/parquet/reader/expression_column_reader.cpp" - -#include "extension/parquet/reader/row_number_column_reader.cpp" +#include "extension/parquet/reader/struct_column_reader.cpp" #include "extension/parquet/reader/list_column_reader.cpp" -#include "extension/parquet/reader/struct_column_reader.cpp" +#include "extension/parquet/reader/decimal_column_reader.cpp" #include "extension/parquet/reader/variant_column_reader.cpp" -#include "extension/parquet/reader/decimal_column_reader.cpp" +#include "extension/parquet/reader/string_column_reader.cpp" + +#include "extension/parquet/reader/expression_column_reader.cpp" + +#include "extension/parquet/reader/row_number_column_reader.cpp" diff --git a/src/duckdb/ub_extension_parquet_writer.cpp b/src/duckdb/ub_extension_parquet_writer.cpp index 4d1eadb19..e1d3beb0f 100644 --- a/src/duckdb/ub_extension_parquet_writer.cpp +++ b/src/duckdb/ub_extension_parquet_writer.cpp @@ -1,16 +1,16 @@ -#include "extension/parquet/writer/array_column_writer.cpp" - #include "extension/parquet/writer/boolean_column_writer.cpp" #include "extension/parquet/writer/struct_column_writer.cpp" -#include "extension/parquet/writer/variant_column_writer.cpp" +#include "extension/parquet/writer/array_column_writer.cpp" -#include "extension/parquet/writer/primitive_column_writer.cpp" +#include "extension/parquet/writer/enum_column_writer.cpp" #include "extension/parquet/writer/list_column_writer.cpp" -#include "extension/parquet/writer/enum_column_writer.cpp" - #include "extension/parquet/writer/decimal_column_writer.cpp" +#include "extension/parquet/writer/primitive_column_writer.cpp" + +#include "extension/parquet/writer/variant_column_writer.cpp" + diff --git a/src/duckdb/ub_extension_parquet_writer_variant.cpp b/src/duckdb/ub_extension_parquet_writer_variant.cpp index 61cb37a96..6e4563d1e 100644 --- a/src/duckdb/ub_extension_parquet_writer_variant.cpp +++ b/src/duckdb/ub_extension_parquet_writer_variant.cpp @@ -1,4 +1,4 @@ -#include "extension/parquet/writer/variant/analyze_variant.cpp" - #include "extension/parquet/writer/variant/convert_variant.cpp" +#include "extension/parquet/writer/variant/analyze_variant.cpp" + diff --git a/src/duckdb/ub_src_function.cpp b/src/duckdb/ub_src_function.cpp index dc9300c5b..81299067b 100644 --- a/src/duckdb/ub_src_function.cpp +++ b/src/duckdb/ub_src_function.cpp @@ -4,6 +4,8 @@ #include "src/function/cast_rules.cpp" +#include "src/function/combine_types_rules.cpp" + #include "src/function/compression_config.cpp" #include "src/function/copy_blob.cpp" diff --git a/src/duckdb/ub_src_function_aggregate_distributive.cpp b/src/duckdb/ub_src_function_aggregate_distributive.cpp index 92bcd6c50..2d4df16a3 100644 --- a/src/duckdb/ub_src_function_aggregate_distributive.cpp +++ b/src/duckdb/ub_src_function_aggregate_distributive.cpp @@ -1,5 +1,7 @@ #include "src/function/aggregate/distributive/count.cpp" +#include "src/function/aggregate/distributive/decimal_avg.cpp" + #include "src/function/aggregate/distributive/first_last_any.cpp" #include "src/function/aggregate/distributive/minmax.cpp" diff --git a/src/duckdb/ub_src_function_scalar_variant.cpp b/src/duckdb/ub_src_function_scalar_variant.cpp index fb6938aed..4d9489559 100644 --- a/src/duckdb/ub_src_function_scalar_variant.cpp +++ b/src/duckdb/ub_src_function_scalar_variant.cpp @@ -1,3 +1,5 @@ +#include "src/function/scalar/variant/variant_array_length.cpp" + #include "src/function/scalar/variant/variant_bind_utils.cpp" #include "src/function/scalar/variant/variant_exists.cpp" diff --git a/src/duckdb/ub_src_main.cpp b/src/duckdb/ub_src_main.cpp index e61f67a80..8df1fa6ca 100644 --- a/src/duckdb/ub_src_main.cpp +++ b/src/duckdb/ub_src_main.cpp @@ -42,20 +42,14 @@ #include "src/main/extension_manager.cpp" -#include "src/main/gathered_metrics.cpp" - #include "src/main/materialized_query_result.cpp" -#include "src/main/metrics_manager.cpp" - #include "src/main/pending_query_result.cpp" #include "src/main/prepared_statement.cpp" #include "src/main/prepared_statement_data.cpp" -#include "src/main/profiling_utils.cpp" - #include "src/main/query_profiler.cpp" #include "src/main/query_result.cpp" diff --git a/src/duckdb/ub_src_main_profiler.cpp b/src/duckdb/ub_src_main_profiler.cpp new file mode 100644 index 000000000..9fbb99086 --- /dev/null +++ b/src/duckdb/ub_src_main_profiler.cpp @@ -0,0 +1,6 @@ +#include "src/main/profiler/gathered_metrics.cpp" + +#include "src/main/profiler/metrics_manager.cpp" + +#include "src/main/profiler/profiling_utils.cpp" +