@@ -616,18 +616,6 @@ DROP TABLE min_max_with_metadata;
616616statement ok
617617RESET datafusion.execution.parquet.skip_metadata;
618618
619- # A CASE whose WHEN is always false simplifies to NULL, which keeps the
620- # extension type of the CASE
621- query T
622- select arrow_metadata(
623- case when 1 = 0 then with_metadata(name, 'ARROW:extension:name', 'a.type') end,
624- 'ARROW:extension:name')
625- from table_with_metadata;
626- ----
627- a.type
628- a.type
629- a.type
630-
631619# coalesce, nvl, ifnull and nvl2: conflicting extension types are a planning error
632620statement error Error during planning: Cannot merge field metadata with differing values of 'ARROW:extension:name': 'a\.type' and 'b\.type'
633621select coalesce(
@@ -708,19 +696,17 @@ select
708696 arrow_metadata(case when id > 1 then name else l_name end, 'metadata_key'),
709697 arrow_metadata(case id when 1 then name else l_name end, 'metadata_key'),
710698 arrow_metadata(
711- case when id > 1
712- then with_metadata(name, 'ARROW:extension:name', 'a.type')
713- else with_metadata(l_name, 'ARROW:extension:name', 'a.type') end,
699+ case when id > 1 then cast(name as json) else cast(l_name as json) end,
714700 'ARROW:extension:name')
715701from table_with_metadata;
716702----
717- the name field the name field a.type
718- the name field the name field a.type
719- the name field the name field a.type
703+ the name field the name field arrow.json
704+ the name field the name field arrow.json
705+ the name field the name field arrow.json
720706
721- statement error Error during planning: Cannot merge field metadata with differing values of 'ARROW:extension:name': 'a\.type ' and 'b\.type'
707+ statement error Error during planning: Cannot merge field metadata with differing values of 'ARROW:extension:name': 'arrow\.json ' and 'b\.type'
722708select case when id > 1
723- then with_metadata (name, 'ARROW:extension:name', 'a.type' )
709+ then cast (name as json )
724710 else with_metadata(l_name, 'ARROW:extension:name', 'b.type') end
725711from table_with_metadata;
726712
@@ -729,74 +715,95 @@ from table_with_metadata;
729715query TTTT
730716select
731717 arrow_metadata(
732- case when id > 1 then upper(name)
733- else with_metadata(l_name, 'ARROW:extension:name', 'a.type') end,
718+ case when id > 1 then upper(name) else cast(l_name as json) end,
734719 'ARROW:extension:name'),
720+ arrow_metadata(coalesce(upper(name), cast(l_name as json)), 'ARROW:extension:name'),
735721 arrow_metadata(
736- coalesce(upper( name), with_metadata(l_name, 'ARROW:extension:name', 'a.type')) ,
722+ case when id > 1 then cast( name as json) else NULL end ,
737723 'ARROW:extension:name'),
724+ arrow_metadata(case when id > 1 then cast(name as json) end, 'ARROW:extension:name')
725+ from table_with_metadata;
726+ ----
727+ arrow.json arrow.json arrow.json arrow.json
728+ arrow.json arrow.json arrow.json arrow.json
729+ arrow.json arrow.json arrow.json arrow.json
730+
731+ # A typed NULL ELSE contributes its metadata, including when no row reaches a
732+ # THEN branch. Each query uses a CASE only once: a repeated expression is
733+ # computed once in a lower projection, whose field comes from the logical plan.
734+ query TT
735+ select
738736 arrow_metadata(
739- case when id > 1 then with_metadata(name, 'ARROW:extension:name', 'a.type')
740- else NULL end,
737+ case when id > 100 then name else cast(NULL as json) end,
741738 'ARROW:extension:name'),
742739 arrow_metadata(
743- case when id > 1 then with_metadata (name, 'ARROW:extension:name', 'a.type' ) end,
740+ case when id > 100 then upper (name) else cast(NULL as json ) end,
744741 'ARROW:extension:name')
745742from table_with_metadata;
746743----
747- a.type a.type a.type a.type
748- a.type a.type a.type a.type
749- a.type a.type a.type a.type
744+ arrow.json arrow.json
745+ arrow.json arrow.json
746+ arrow.json arrow.json
750747
751- # A typed NULL ELSE with metadata contributes its metadata, including when no
752- # row reaches a THEN branch
753- query TTTT
748+ query TT
754749select
755- case when id > 100 then name
756- else with_metadata(arrow_cast(NULL, 'Utf8'), 'source', 'null_else') end,
750+ case when id > 100 then name else cast(NULL as json) end,
751+ case when id > 100 then upper(name) else cast(NULL as json) end
752+ from table_with_metadata;
753+ ----
754+ NULL NULL
755+ NULL NULL
756+ NULL NULL
757+
758+ # Coercing the branches to a common type casts a branch to a plain storage type,
759+ # which drops its extension type and keeps its other metadata
760+ query TTT
761+ select
762+ arrow_typeof(
763+ case when id > 1 then cast(name as json) else arrow_cast(l_name, 'LargeUtf8') end),
757764 arrow_metadata(
758- case when id > 100 then name
759- else with_metadata(arrow_cast(NULL, 'Utf8'), 'source', 'null_else') end,
760- 'source'),
761- case when id > 100 then upper(name)
762- else with_metadata(arrow_cast(NULL, 'Utf8'), 'source', 'null_else') end,
765+ case when id > 1 then cast(name as json) else arrow_cast(l_name, 'LargeUtf8') end,
766+ 'ARROW:extension:name'),
763767 arrow_metadata(
764- case when id > 100 then upper(name)
765- else with_metadata(arrow_cast(NULL, 'Utf8'), 'source', 'null_else') end,
766- 'source')
768+ case when id > 1 then name else arrow_cast(l_name, 'LargeUtf8') end,
769+ 'metadata_key')
767770from table_with_metadata;
768771----
769- NULL null_else NULL null_else
770- NULL null_else NULL null_else
771- NULL null_else NULL null_else
772+ LargeUtf8 NULL the name field
773+ LargeUtf8 NULL the name field
774+ LargeUtf8 NULL the name field
772775
773776# Nested CASE, and the CASE rewrites of coalesce, nvl, ifnull and nvl2, keep
774- # the extension type at execution
777+ # the extension type at execution. The rewrites take different arguments so
778+ # that they are not one repeated expression.
775779query TTTTT
776780select
777781 arrow_metadata(
778782 case when id > 1
779- then case when id > 2
780- then with_metadata(name, 'ARROW:extension:name', 'a.type') end
783+ then case when id > 2 then cast(name as json) end
781784 else l_name end,
782785 'ARROW:extension:name'),
783- arrow_metadata(
784- coalesce(with_metadata(name, 'ARROW:extension:name', 'a.type'), l_name),
785- 'ARROW:extension:name'),
786- arrow_metadata(
787- nvl(with_metadata(name, 'ARROW:extension:name', 'a.type'), l_name),
788- 'ARROW:extension:name'),
789- arrow_metadata(
790- ifnull(with_metadata(name, 'ARROW:extension:name', 'a.type'), l_name),
791- 'ARROW:extension:name'),
792- arrow_metadata(
793- nvl2(id, with_metadata(name, 'ARROW:extension:name', 'a.type'), l_name),
794- 'ARROW:extension:name')
786+ arrow_metadata(coalesce(cast(name as json), l_name), 'ARROW:extension:name'),
787+ arrow_metadata(nvl(cast(name as json), upper(l_name)), 'ARROW:extension:name'),
788+ arrow_metadata(ifnull(cast(name as json), lower(l_name)), 'ARROW:extension:name'),
789+ arrow_metadata(nvl2(id, cast(name as json), l_name), 'ARROW:extension:name')
790+ from table_with_metadata;
791+ ----
792+ arrow.json arrow.json arrow.json arrow.json arrow.json
793+ arrow.json arrow.json arrow.json arrow.json arrow.json
794+ arrow.json arrow.json arrow.json arrow.json arrow.json
795+
796+ # A CASE whose WHEN is always false simplifies to NULL, which keeps the
797+ # extension type of the CASE
798+ query T
799+ select arrow_metadata(
800+ case when 1 = 0 then cast(name as json) end,
801+ 'ARROW:extension:name')
795802from table_with_metadata;
796803----
797- a.type a.type a.type a.type a.type
798- a.type a.type a.type a.type a.type
799- a.type a.type a.type a.type a.type
804+ arrow.json
805+ arrow.json
806+ arrow.json
800807
801808statement ok
802809drop table table_with_metadata;
0 commit comments