This is an automated email from the ASF dual-hosted git repository.

wenchen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 65e62283fd0c [SPARK-52494][SQL] Support colon-sign operator syntax to 
access Variant fields
65e62283fd0c is described below

commit 65e62283fd0c555012d818d6d7b40adae95b5e91
Author: Haoyan Geng <[email protected]>
AuthorDate: Fri Jun 27 17:30:16 2025 +0800

    [SPARK-52494][SQL] Support colon-sign operator syntax to access Variant 
fields
    
    ### What changes were proposed in this pull request?
    
    Adds support for accessing fields inside a Variant data type through the 
colon-sign operator.  The syntax is documented here: 
https://docs.databricks.com/aws/en/sql/language-manual/functions/colonsign
    
    ### Why are the changes needed?
    
    Provides a convenient way to access fields inside a Variant via SQL.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes -- The previously invalid (would throw ParseException) syntax is now 
supported.
    
    === In Scala Spark shell:
    
    Before:
    ```
    scala> spark.sql("SELECT PARSE_JSON('{ \"price\": 5 }'):price").collect
    warning: 1 deprecation (since 2.13.3); for details, enable `:setting 
-deprecation` or `:replay -deprecation`
    org.apache.spark.sql.catalyst.parser.ParseException:
    [PARSE_SYNTAX_ERROR] Syntax error at or near ':'. SQLSTATE: 42601 (line 1, 
pos 35)
    
    == SQL ==
    SELECT PARSE_JSON('{ "price": 5 }'):price
    -----------------------------------^^^
    
      at 
org.apache.spark.sql.catalyst.parser.ParseException.withCommand(parsers.scala:274)
      at 
org.apache.spark.sql.catalyst.parser.AbstractParser.parse(parsers.scala:97)
      at 
org.apache.spark.sql.execution.SparkSqlParser.parse(SparkSqlParser.scala:54)
      at 
org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parsePlan(AbstractSqlParser.scala:93)
      at 
org.apache.spark.sql.classic.SparkSession.$anonfun$sql$5(SparkSession.scala:492)
      at 
org.apache.spark.sql.catalyst.QueryPlanningTracker.measurePhase(QueryPlanningTracker.scala:148)
      at 
org.apache.spark.sql.classic.SparkSession.$anonfun$sql$4(SparkSession.scala:491)
      at org.apache.spark.sql.SparkSession.withActive(SparkSession.scala:804)
      at org.apache.spark.sql.classic.SparkSession.sql(SparkSession.scala:490)
      at org.apache.spark.sql.classic.SparkSession.sql(SparkSession.scala:504)
      at org.apache.spark.sql.classic.SparkSession.sql(SparkSession.scala:513)
      at org.apache.spark.sql.classic.SparkSession.sql(SparkSession.scala:91)
      ... 42 elided
    ```
    
    After:
    ```
    scala> spark.sql("SELECT PARSE_JSON('{ \"price\": 5 }'):price").collect
    val res0: Array[org.apache.spark.sql.Row] = Array([5])
    ```
    
    === In PySpark REPL:
    
    Before:
    >>> spark.sql("select parse_json('{ \"price\": 5 }'):price::int").collect()
    Traceback (most recent call last):
      File "<python-input-0>", line 1, in <module>
        spark.sql("select parse_json('{ \"price\": 5 }'):price::int").collect()
        ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/haoyan.geng/oss-scala/python/pyspark/sql/session.py", line 
1810, in sql
        return DataFrame(self._jsparkSession.sql(sqlQuery, litArgs), self)
                         ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
      File 
"/Users/haoyan.geng/oss-scala/python/lib/py4j-0.10.9.9-src.zip/py4j/java_gateway.py",
 line 1362, in __call__
        return_value = get_return_value(
            answer, self.gateway_client, self.target_id, self.name)
      File 
"/Users/haoyan.geng/oss-scala/python/pyspark/errors/exceptions/captured.py", 
line 294, in deco
        raise converted from None
    pyspark.errors.exceptions.captured.ParseException:
    [PARSE_SYNTAX_ERROR] Syntax error at or near ':'. SQLSTATE: 42601 (line 1, 
pos 35)
    
    == SQL ==
    select parse_json('{ "price": 5 }'):price::int
    -----------------------------------^^^
    
    After:
    >>> spark.sql("select parse_json('{ \"price\": 5 }'):price::int").collect()
    [Row(price=5)]
    
    ### How was this patch tested?
    - Added new test cases in SQLQueryTestSuite 
(sql/core/src/test/resources/sql-tests/inputs/variant-field-extractions.sql).
    - Manually tested the new behavior in Spark Shell (Scala) and PySpark REPL.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    No
    
    Closes #51190 from haoyangeng-db/colon-op.
    
    Authored-by: Haoyan Geng <[email protected]>
    Signed-off-by: Wenchen Fan <[email protected]>
---
 .../spark/sql/catalyst/parser/SqlBaseParser.g4     |  27 ++
 .../expressions/SemiStructuredExtract.scala        |  60 +++
 .../expressions/json/JsonExpressionEvalUtils.scala |   8 +-
 .../spark/sql/catalyst/parser/AstBuilder.scala     |  20 +
 .../sql/catalyst/rules/RuleIdCollection.scala      |   1 +
 .../spark/sql/catalyst/trees/TreePatterns.scala    |   1 +
 .../sql/internal/BaseSessionStateBuilder.scala     |   3 +-
 .../variant-field-extractions.sql.out              | 457 +++++++++++++++++++++
 .../sql-tests/inputs/variant-field-extractions.sql |  74 ++++
 .../results/variant-field-extractions.sql.out      | 343 ++++++++++++++++
 .../thriftserver/ThriftServerQueryTestSuite.scala  |   1 +
 .../spark/sql/hive/HiveSessionStateBuilder.scala   |   3 +-
 12 files changed, 992 insertions(+), 6 deletions(-)

diff --git 
a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 
b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
index 9177fd8ba1a1..fc3d86ca858f 100644
--- 
a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
+++ 
b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
@@ -1208,6 +1208,7 @@ primaryExpression
     | constant                                                                 
                #constantDefault
     | ASTERISK exceptClause?                                                   
                #star
     | qualifiedName DOT ASTERISK exceptClause?                                 
                #star
+    | col=primaryExpression COLON path=semiStructuredExtractionPath            
                #semiStructuredExtract
     | LEFT_PAREN namedExpression (COMMA namedExpression)+ RIGHT_PAREN          
                #rowConstructor
     | LEFT_PAREN query RIGHT_PAREN                                             
                #subqueryExpression
     | functionName LEFT_PAREN (setQuantifier? argument+=functionArgument
@@ -1230,6 +1231,32 @@ primaryExpression
       FROM position=valueExpression (FOR length=valueExpression)? RIGHT_PAREN  
                #overlay
     ;
 
+semiStructuredExtractionPath
+    : jsonPathFirstPart (jsonPathParts)*
+    ;
+
+jsonPathIdentifier
+    : identifier
+    | BACKQUOTED_IDENTIFIER
+    ;
+
+jsonPathBracketedIdentifier
+    : LEFT_BRACKET stringLit RIGHT_BRACKET
+    ;
+
+jsonPathFirstPart
+    : jsonPathIdentifier
+    | jsonPathBracketedIdentifier
+    | LEFT_BRACKET INTEGER_VALUE RIGHT_BRACKET
+    ;
+
+jsonPathParts
+    : DOT jsonPathIdentifier
+    | jsonPathBracketedIdentifier
+    | LEFT_BRACKET INTEGER_VALUE RIGHT_BRACKET
+    | LEFT_BRACKET identifier RIGHT_BRACKET
+    ;
+
 literalType
     : DATE
     | TIME
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SemiStructuredExtract.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SemiStructuredExtract.scala
new file mode 100644
index 000000000000..af5d2ec39d00
--- /dev/null
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/SemiStructuredExtract.scala
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.sql.catalyst.expressions
+
+import org.apache.spark.sql.AnalysisException
+import org.apache.spark.sql.catalyst.expressions.variant.VariantGet
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.catalyst.rules.Rule
+import 
org.apache.spark.sql.catalyst.trees.TreePattern.{SEMI_STRUCTURED_EXTRACT, 
TreePattern}
+import org.apache.spark.sql.types.{DataType, StringType, VariantType}
+import org.apache.spark.unsafe.types.UTF8String
+
+/**
+ * Represents the extraction of data from a field that contains 
semi-structured data. The
+ * semi-structured column can only be a Variant type for now.
+ * @param child The semi-structured column
+ * @param field The field to extract
+ */
+case class SemiStructuredExtract(
+    child: Expression, field: String) extends UnaryExpression with Unevaluable 
{
+  override lazy val resolved = false
+  override def dataType: DataType = StringType
+
+  final override val nodePatterns: Seq[TreePattern] = 
Seq(SEMI_STRUCTURED_EXTRACT)
+
+  override protected def withNewChildInternal(newChild: Expression): 
SemiStructuredExtract =
+    copy(child = newChild)
+}
+
+/**
+ * Replaces SemiStructuredExtract expressions by extracting the specified 
field from the
+ * semi-structured column (only VariantType is supported for now).
+ */
+case object ExtractSemiStructuredFields extends Rule[LogicalPlan] {
+  override def apply(plan: LogicalPlan): LogicalPlan = 
plan.resolveExpressionsWithPruning(
+    _.containsPattern(SEMI_STRUCTURED_EXTRACT), ruleId) {
+    case SemiStructuredExtract(column, field) if column.resolved =>
+      if (column.dataType.isInstanceOf[VariantType]) {
+        VariantGet(column, Literal(UTF8String.fromString(field)), VariantType, 
failOnError = true)
+      } else {
+        throw new AnalysisException(
+          errorClass = "COLUMN_IS_NOT_VARIANT_TYPE", messageParameters = 
Map.empty)
+      }
+  }
+}
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/json/JsonExpressionEvalUtils.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/json/JsonExpressionEvalUtils.scala
index b942006e87e9..f0473f5a414f 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/json/JsonExpressionEvalUtils.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/json/JsonExpressionEvalUtils.scala
@@ -33,13 +33,13 @@ import org.apache.spark.sql.types.{ArrayType, DataType, 
MapType, StringType, Str
 import org.apache.spark.unsafe.types.{UTF8String, VariantVal}
 import org.apache.spark.util.Utils
 
-private[this] sealed trait PathInstruction
-private[this] object PathInstruction {
+sealed trait PathInstruction
+object PathInstruction {
   private[expressions] case object Subscript extends PathInstruction
   private[expressions] case object Wildcard extends PathInstruction
   private[expressions] case object Key extends PathInstruction
   private[expressions] case class Index(index: Long) extends PathInstruction
-  private[expressions] case class Named(name: String) extends PathInstruction
+  case class Named(name: String) extends PathInstruction
 }
 
 private[this] sealed trait WriteStyle
@@ -49,7 +49,7 @@ private[this] object WriteStyle {
   private[expressions] case object FlattenStyle extends WriteStyle
 }
 
-private[this] object JsonPathParser extends RegexParsers {
+object JsonPathParser extends RegexParsers {
   import PathInstruction._
 
   def root: Parser[Char] = '$'
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index 9b9ff2175457..54528f706b03 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -36,6 +36,8 @@ import 
org.apache.spark.sql.catalyst.analysis.FunctionRegistry.FUNC_ALIAS
 import org.apache.spark.sql.catalyst.catalog.{BucketSpec, 
CatalogStorageFormat, ClusterBySpec}
 import org.apache.spark.sql.catalyst.expressions._
 import org.apache.spark.sql.catalyst.expressions.aggregate.{AnyValue, First, 
Last}
+import org.apache.spark.sql.catalyst.expressions.json.JsonPathParser
+import org.apache.spark.sql.catalyst.expressions.json.PathInstruction.Named
 import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
 import org.apache.spark.sql.catalyst.plans._
 import org.apache.spark.sql.catalyst.plans.logical._
@@ -3322,6 +3324,24 @@ class AstBuilder extends DataTypeAstBuilder
     }
   }
 
+  /**
+   * Create a [[SemiStructuredExtract]] expression.
+   */
+  override def visitSemiStructuredExtract(
+      ctx: SemiStructuredExtractContext): Expression = withOrigin(ctx) {
+    val field = ctx.path.getText
+    // When `field` starts with a bracket, do not add a `.` as the bracket 
already implies nesting
+    // Also the bracket will imply case sensitive field extraction.
+    val path = if (field.startsWith("[")) "$" + field else s"$$.$field"
+    val parsedPath = JsonPathParser.parse(path)
+    if (parsedPath.isEmpty) {
+      throw new ParseException(errorClass = "PARSE_SYNTAX_ERROR", ctx = ctx)
+    }
+    val potentialAlias = parsedPath.get.collect { case Named(name) => name 
}.lastOption
+    val node = SemiStructuredExtract(expression(ctx.col), path)
+    potentialAlias.map { colName => Alias(node, colName)() }.getOrElse(node)
+  }
+
   /**
    * Create an [[UnresolvedAttribute]] expression or a [[UnresolvedRegex]] if 
it is a regex
    * quoted in ``
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/rules/RuleIdCollection.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/rules/RuleIdCollection.scala
index 0d376861ddfb..e7b59af5e776 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/rules/RuleIdCollection.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/rules/RuleIdCollection.scala
@@ -113,6 +113,7 @@ object RuleIdCollection {
       
"org.apache.spark.sql.catalyst.expressions.ValidateAndStripPipeExpressions" ::
       "org.apache.spark.sql.catalyst.analysis.ResolveUnresolvedHaving" ::
       "org.apache.spark.sql.catalyst.analysis.ResolveTableConstraints" ::
+      "org.apache.spark.sql.catalyst.expressions.ExtractSemiStructuredFields" 
::
       // Catalyst Optimizer rules
       "org.apache.spark.sql.catalyst.optimizer.BooleanSimplification" ::
       "org.apache.spark.sql.catalyst.optimizer.CollapseProject" ::
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreePatterns.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreePatterns.scala
index 471e68b6b708..c35aa7403d76 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreePatterns.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreePatterns.scala
@@ -80,6 +80,7 @@ object TreePattern extends Enumeration  {
   val REGEXP_EXTRACT_FAMILY: Value = Value
   val REGEXP_REPLACE: Value = Value
   val RUNTIME_REPLACEABLE: Value = Value
+  val SEMI_STRUCTURED_EXTRACT: Value = Value
   val SCALAR_SUBQUERY: Value = Value
   val SCALAR_SUBQUERY_REFERENCE: Value = Value
   val SCALA_UDF: Value = Value
diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/internal/BaseSessionStateBuilder.scala
 
b/sql/core/src/main/scala/org/apache/spark/sql/internal/BaseSessionStateBuilder.scala
index 334616a7709e..9942918638c5 100644
--- 
a/sql/core/src/main/scala/org/apache/spark/sql/internal/BaseSessionStateBuilder.scala
+++ 
b/sql/core/src/main/scala/org/apache/spark/sql/internal/BaseSessionStateBuilder.scala
@@ -22,7 +22,7 @@ import org.apache.spark.sql.artifact.ArtifactManager
 import org.apache.spark.sql.catalyst.analysis.{Analyzer, 
EvalSubqueriesForTimeTravel, FunctionRegistry, InvokeProcedures, 
ReplaceCharWithVarchar, ResolveDataSource, ResolveSessionCatalog, 
ResolveTranspose, TableFunctionRegistry}
 import org.apache.spark.sql.catalyst.analysis.resolver.ResolverExtension
 import org.apache.spark.sql.catalyst.catalog.{FunctionExpressionBuilder, 
SessionCatalog}
-import org.apache.spark.sql.catalyst.expressions.Expression
+import org.apache.spark.sql.catalyst.expressions.{Expression, 
ExtractSemiStructuredFields}
 import org.apache.spark.sql.catalyst.optimizer.Optimizer
 import org.apache.spark.sql.catalyst.parser.ParserInterface
 import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
@@ -244,6 +244,7 @@ abstract class BaseSessionStateBuilder(
         new EvalSubqueriesForTimeTravel +:
         new ResolveTranspose(session) +:
         new InvokeProcedures(session) +:
+        ExtractSemiStructuredFields +:
         customResolutionRules
 
     override val postHocResolutionRules: Seq[Rule[LogicalPlan]] =
diff --git 
a/sql/core/src/test/resources/sql-tests/analyzer-results/variant-field-extractions.sql.out
 
b/sql/core/src/test/resources/sql-tests/analyzer-results/variant-field-extractions.sql.out
new file mode 100644
index 000000000000..d95fb80980b8
--- /dev/null
+++ 
b/sql/core/src/test/resources/sql-tests/analyzer-results/variant-field-extractions.sql.out
@@ -0,0 +1,457 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW variant_test_data AS
+SELECT
+  parse_json('{ "price": 30 }') as int_price_variant,
+  parse_json('{ "price": 12345.678 }') as double_price_variant,
+  parse_json('{ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }') as multi_field_variant,
+  parse_json('{ "item": [ { "model" : "basic", "price" : 6.12 }, { "model" : 
"medium", "price" : 9.24 } ] }') as array_value_variant,
+  parse_json('[{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }, { 
"id": 3, "name": "Charlie" }]') as array_variant,
+  parse_json('{ "metadata": { "version": "1.0", "tags": ["important", 
"urgent"], "nested": { "level": 2, "value": "deep" } } }') as nested_variant,
+  parse_json('{ "field-name": "value1", "field.name": "value2", "field_name": 
"value3" }') as special_chars_variant
+-- !query analysis
+CreateViewCommand `variant_test_data`, SELECT
+  parse_json('{ "price": 30 }') as int_price_variant,
+  parse_json('{ "price": 12345.678 }') as double_price_variant,
+  parse_json('{ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }') as multi_field_variant,
+  parse_json('{ "item": [ { "model" : "basic", "price" : 6.12 }, { "model" : 
"medium", "price" : 9.24 } ] }') as array_value_variant,
+  parse_json('[{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }, { 
"id": 3, "name": "Charlie" }]') as array_variant,
+  parse_json('{ "metadata": { "version": "1.0", "tags": ["important", 
"urgent"], "nested": { "level": 2, "value": "deep" } } }') as nested_variant,
+  parse_json('{ "field-name": "value1", "field.name": "value2", "field_name": 
"value3" }') as special_chars_variant, false, false, LocalTempView, 
UNSUPPORTED, true
+   +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { "id": 3 [...]
+      +- OneRowRelation
+
+
+-- !query
+select int_price_variant:price from variant_test_data
+-- !query analysis
+Project [variant_get(int_price_variant#x, $.price, VariantType, true, 
Some(America/Los_Angeles)) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select int_price_variant:price::decimal(5, 2) from variant_test_data
+-- !query analysis
+Project [cast(variant_get(int_price_variant#x, $.price, VariantType, true, 
Some(America/Los_Angeles)) as decimal(5,2)) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select int_price_variant:price::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(int_price_variant#x, $.price, VariantType, true, 
Some(America/Los_Angeles)) as string) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select double_price_variant:price::decimal(3, 2) from variant_test_data
+-- !query analysis
+Project [cast(variant_get(double_price_variant#x, $.price, VariantType, true, 
Some(America/Los_Angeles)) as decimal(3,2)) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:name, multi_field_variant:age, 
multi_field_variant:city from variant_test_data
+-- !query analysis
+Project [variant_get(multi_field_variant#x, $.name, VariantType, true, 
Some(America/Los_Angeles)) AS name#x, variant_get(multi_field_variant#x, $.age, 
VariantType, true, Some(America/Los_Angeles)) AS age#x, 
variant_get(multi_field_variant#x, $.city, VariantType, true, 
Some(America/Los_Angeles)) AS city#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:name::string, multi_field_variant:age::int, 
multi_field_variant:active::boolean from variant_test_data
+-- !query analysis
+Project [cast(variant_get(multi_field_variant#x, $.name, VariantType, true, 
Some(America/Los_Angeles)) as string) AS name#x, 
cast(variant_get(multi_field_variant#x, $.age, VariantType, true, 
Some(America/Los_Angeles)) as int) AS age#x, 
cast(variant_get(multi_field_variant#x, $.active, VariantType, true, 
Some(America/Los_Angeles)) as boolean) AS active#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:['name'] from variant_test_data
+-- !query analysis
+Project [variant_get(multi_field_variant#x, $['name'], VariantType, true, 
Some(America/Los_Angeles)) AS name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:['age'] from variant_test_data
+-- !query analysis
+Project [variant_get(multi_field_variant#x, $['age'], VariantType, true, 
Some(America/Los_Angeles)) AS age#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_value_variant:item[0].model from variant_test_data
+-- !query analysis
+Project [variant_get(array_value_variant#x, $.item[0].model, VariantType, 
true, Some(America/Los_Angeles)) AS model#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_value_variant:item[0].price from variant_test_data
+-- !query analysis
+Project [variant_get(array_value_variant#x, $.item[0].price, VariantType, 
true, Some(America/Los_Angeles)) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_value_variant:item[1].model from variant_test_data
+-- !query analysis
+Project [variant_get(array_value_variant#x, $.item[1].model, VariantType, 
true, Some(America/Los_Angeles)) AS model#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_value_variant:item[1].price from variant_test_data
+-- !query analysis
+Project [variant_get(array_value_variant#x, $.item[1].price, VariantType, 
true, Some(America/Los_Angeles)) AS price#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_variant:[0].id from variant_test_data
+-- !query analysis
+Project [variant_get(array_variant#x, $[0].id, VariantType, true, 
Some(America/Los_Angeles)) AS id#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_variant:[0].name from variant_test_data
+-- !query analysis
+Project [variant_get(array_variant#x, $[0].name, VariantType, true, 
Some(America/Los_Angeles)) AS name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_variant:[1].id from variant_test_data
+-- !query analysis
+Project [variant_get(array_variant#x, $[1].id, VariantType, true, 
Some(America/Los_Angeles)) AS id#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select array_variant:[1].name from variant_test_data
+-- !query analysis
+Project [variant_get(array_variant#x, $[1].name, VariantType, true, 
Some(America/Los_Angeles)) AS name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata.version from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata.version, VariantType, true, 
Some(America/Los_Angeles)) AS version#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata.tags[0] from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata.tags[0], VariantType, true, 
Some(America/Los_Angeles)) AS tags#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata.nested.level from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata.nested.level, VariantType, 
true, Some(America/Los_Angeles)) AS level#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata.nested.value from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata.nested.value, VariantType, 
true, Some(America/Los_Angeles)) AS value#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata['version'] from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata['version'], VariantType, 
true, Some(America/Los_Angeles)) AS version#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select nested_variant:metadata['tags'] from variant_test_data
+-- !query analysis
+Project [variant_get(nested_variant#x, $.metadata['tags'], VariantType, true, 
Some(America/Los_Angeles)) AS tags#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:`field-name`::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $.field-name, VariantType, 
true, Some(America/Los_Angeles)) as string) AS field-name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:['field-name']::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $['field-name'], 
VariantType, true, Some(America/Los_Angeles)) as string) AS field-name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:field_name::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $.field_name, VariantType, 
true, Some(America/Los_Angeles)) as string) AS field_name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:['field_name']::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $['field_name'], 
VariantType, true, Some(America/Los_Angeles)) as string) AS field_name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:`field.name`::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $.field.name, VariantType, 
true, Some(America/Los_Angeles)) as string) AS name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select special_chars_variant:['field.name']::string from variant_test_data
+-- !query analysis
+Project [cast(variant_get(special_chars_variant#x, $['field.name'], 
VariantType, true, Some(America/Los_Angeles)) as string) AS field.name#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:scores[0]::int + multi_field_variant:scores[1]::int 
from variant_test_data
+-- !query analysis
+Project [(cast(variant_get(multi_field_variant#x, $.scores[0], VariantType, 
true, Some(America/Los_Angeles)) as int) + 
cast(variant_get(multi_field_variant#x, $.scores[1], VariantType, true, 
Some(America/Los_Angeles)) as int)) AS (CAST(variant_get(multi_field_variant, 
$.scores[0]) AS scores AS INT) + CAST(variant_get(multi_field_variant, 
$.scores[1]) AS scores AS INT))#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select count(*) from (select explode(cast(multi_field_variant:scores as 
array<int>)) as score from variant_test_data)
+-- !query analysis
+Aggregate [count(1) AS count(1)#xL]
++- SubqueryAlias __auto_generated_subquery_name
+   +- Project [score#x]
+      +- Generate explode(cast(variant_get(multi_field_variant#x, $.scores, 
VariantType, true, Some(America/Los_Angeles)) as array<int>)), false, [score#x]
+         +- SubqueryAlias variant_test_data
+            +- View (`variant_test_data`, [int_price_variant#x, 
double_price_variant#x, multi_field_variant#x, array_value_variant#x, 
array_variant#x, nested_variant#x, special_chars_variant#x])
+               +- Project [cast(int_price_variant#x as variant) AS 
int_price_variant#x, cast(double_price_variant#x as variant) AS 
double_price_variant#x, cast(multi_field_variant#x as variant) AS 
multi_field_variant#x, cast(array_value_variant#x as variant) AS 
array_value_variant#x, cast(array_variant#x as variant) AS array_variant#x, 
cast(nested_variant#x as variant) AS nested_variant#x, 
cast(special_chars_variant#x as variant) AS special_chars_variant#x]
+                  +- Project [parse_json({ "price": 30 }, true) AS 
int_price_variant#x, parse_json({ "price": 12345.678 }, true) AS 
double_price_variant#x, parse_json({ "name": "John", "age": 30, "city": "New 
York", "active": true, "scores": [85, 92, 78] }, true) AS 
multi_field_variant#x, parse_json({ "item": [ { "model" : "basic", "price" : 
6.12 }, { "model" : "medium", "price" : 9.24 } ] }, true) AS 
array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, { "id": 2, 
"name": "Bo [...]
+                     +- OneRowRelation
+
+
+-- !query
+select * from variant_test_data
+-- !query analysis
+Project [int_price_variant#x, double_price_variant#x, multi_field_variant#x, 
array_value_variant#x, array_variant#x, nested_variant#x, 
special_chars_variant#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select multi_field_variant:* from variant_test_data
+-- !query analysis
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'*'",
+    "hint" : ""
+  }
+}
+
+
+-- !query
+select typeof(multi_field_variant:name) from variant_test_data
+-- !query analysis
+Project [typeof(variant_get(multi_field_variant#x, $.name, VariantType, true, 
Some(America/Los_Angeles))) AS typeof(variant_get(multi_field_variant, $.name) 
AS name)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select typeof(multi_field_variant:age) from variant_test_data
+-- !query analysis
+Project [typeof(variant_get(multi_field_variant#x, $.age, VariantType, true, 
Some(America/Los_Angeles))) AS typeof(variant_get(multi_field_variant, $.age) 
AS age)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select typeof(multi_field_variant:active) from variant_test_data
+-- !query analysis
+Project [typeof(variant_get(multi_field_variant#x, $.active, VariantType, 
true, Some(America/Los_Angeles))) AS typeof(variant_get(multi_field_variant, 
$.active) AS active)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select typeof(multi_field_variant:scores) from variant_test_data
+-- !query analysis
+Project [typeof(variant_get(multi_field_variant#x, $.scores, VariantType, 
true, Some(America/Los_Angeles))) AS typeof(variant_get(multi_field_variant, 
$.scores) AS scores)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select isnull(multi_field_variant:missing_field) from variant_test_data
+-- !query analysis
+Project [isnull(variant_get(multi_field_variant#x, $.missing_field, 
VariantType, true, Some(America/Los_Angeles))) AS 
(variant_get(multi_field_variant, $.missing_field) AS missing_field IS NULL)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select isnotnull(multi_field_variant:name) from variant_test_data
+-- !query analysis
+Project [isnotnull(variant_get(multi_field_variant#x, $.name, VariantType, 
true, Some(America/Los_Angeles))) AS (variant_get(multi_field_variant, $.name) 
AS name IS NOT NULL)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
+
+
+-- !query
+select coalesce(multi_field_variant:missing_field, 'default_value') from 
variant_test_data
+-- !query analysis
+Project [coalesce(variant_get(multi_field_variant#x, $.missing_field, 
VariantType, true, Some(America/Los_Angeles)), cast(default_value as variant)) 
AS coalesce(variant_get(multi_field_variant, $.missing_field) AS missing_field, 
default_value)#x]
++- SubqueryAlias variant_test_data
+   +- View (`variant_test_data`, [int_price_variant#x, double_price_variant#x, 
multi_field_variant#x, array_value_variant#x, array_variant#x, 
nested_variant#x, special_chars_variant#x])
+      +- Project [cast(int_price_variant#x as variant) AS int_price_variant#x, 
cast(double_price_variant#x as variant) AS double_price_variant#x, 
cast(multi_field_variant#x as variant) AS multi_field_variant#x, 
cast(array_value_variant#x as variant) AS array_value_variant#x, 
cast(array_variant#x as variant) AS array_variant#x, cast(nested_variant#x as 
variant) AS nested_variant#x, cast(special_chars_variant#x as variant) AS 
special_chars_variant#x]
+         +- Project [parse_json({ "price": 30 }, true) AS int_price_variant#x, 
parse_json({ "price": 12345.678 }, true) AS double_price_variant#x, 
parse_json({ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }, true) AS multi_field_variant#x, parse_json({ "item": 
[ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } 
] }, true) AS array_value_variant#x, parse_json([{ "id": 1, "name": "Alice" }, 
{ "id": 2, "name": "Bob" }, { " [...]
+            +- OneRowRelation
diff --git 
a/sql/core/src/test/resources/sql-tests/inputs/variant-field-extractions.sql 
b/sql/core/src/test/resources/sql-tests/inputs/variant-field-extractions.sql
new file mode 100644
index 000000000000..3a5a3c454db9
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/variant-field-extractions.sql
@@ -0,0 +1,74 @@
+-- Create temp view with Variant columns for testing field extraction and type 
casting.
+CREATE TEMP VIEW variant_test_data AS
+SELECT
+  parse_json('{ "price": 30 }') as int_price_variant,
+  parse_json('{ "price": 12345.678 }') as double_price_variant,
+  parse_json('{ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }') as multi_field_variant,
+  parse_json('{ "item": [ { "model" : "basic", "price" : 6.12 }, { "model" : 
"medium", "price" : 9.24 } ] }') as array_value_variant,
+  parse_json('[{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }, { 
"id": 3, "name": "Charlie" }]') as array_variant,
+  parse_json('{ "metadata": { "version": "1.0", "tags": ["important", 
"urgent"], "nested": { "level": 2, "value": "deep" } } }') as nested_variant,
+  parse_json('{ "field-name": "value1", "field.name": "value2", "field_name": 
"value3" }') as special_chars_variant;
+
+-- Single field extraction and type casting.
+select int_price_variant:price from variant_test_data;
+select int_price_variant:price::decimal(5, 2) from variant_test_data;
+select int_price_variant:price::string from variant_test_data;
+
+-- Applying an invalid function -- will throw an error.
+select double_price_variant:price::decimal(3, 2) from variant_test_data;
+
+-- Multi-field access.
+select multi_field_variant:name, multi_field_variant:age, 
multi_field_variant:city from variant_test_data;
+select multi_field_variant:name::string, multi_field_variant:age::int, 
multi_field_variant:active::boolean from variant_test_data;
+select multi_field_variant:['name'] from variant_test_data;
+select multi_field_variant:['age'] from variant_test_data;
+
+-- Array value access.
+select array_value_variant:item[0].model from variant_test_data;
+select array_value_variant:item[0].price from variant_test_data;
+select array_value_variant:item[1].model from variant_test_data;
+select array_value_variant:item[1].price from variant_test_data;
+
+-- Array access.
+select array_variant:[0].id from variant_test_data;
+select array_variant:[0].name from variant_test_data;
+select array_variant:[1].id from variant_test_data;
+select array_variant:[1].name from variant_test_data;
+
+-- Nested field access.
+select nested_variant:metadata.version from variant_test_data;
+select nested_variant:metadata.tags[0] from variant_test_data;
+select nested_variant:metadata.nested.level from variant_test_data;
+select nested_variant:metadata.nested.value from variant_test_data;
+select nested_variant:metadata['version'] from variant_test_data;
+select nested_variant:metadata['tags'] from variant_test_data;
+
+-- Special characters.
+select special_chars_variant:`field-name`::string from variant_test_data;
+select special_chars_variant:['field-name']::string from variant_test_data;
+select special_chars_variant:field_name::string from variant_test_data;
+select special_chars_variant:['field_name']::string from variant_test_data;
+-- Not supported; will return NULL.
+select special_chars_variant:`field.name`::string from variant_test_data;
+-- Using [] is okay.
+select special_chars_variant:['field.name']::string from variant_test_data;
+
+-- Array operations on Variant arrays.
+select multi_field_variant:scores[0]::int + multi_field_variant:scores[1]::int 
from variant_test_data;
+select count(*) from (select explode(cast(multi_field_variant:scores as 
array<int>)) as score from variant_test_data);
+
+-- ASTERISK syntax.
+select * from variant_test_data;
+-- Not supported; will throw an error.
+select multi_field_variant:* from variant_test_data;
+
+-- Type checking: The result of the following would all be 'variant'.
+select typeof(multi_field_variant:name) from variant_test_data;
+select typeof(multi_field_variant:age) from variant_test_data;
+select typeof(multi_field_variant:active) from variant_test_data;
+select typeof(multi_field_variant:scores) from variant_test_data;
+
+-- Variant field access with NULL handling.
+select isnull(multi_field_variant:missing_field) from variant_test_data;
+select isnotnull(multi_field_variant:name) from variant_test_data;
+select coalesce(multi_field_variant:missing_field, 'default_value') from 
variant_test_data;
diff --git 
a/sql/core/src/test/resources/sql-tests/results/variant-field-extractions.sql.out
 
b/sql/core/src/test/resources/sql-tests/results/variant-field-extractions.sql.out
new file mode 100644
index 000000000000..a5f0436d9b11
--- /dev/null
+++ 
b/sql/core/src/test/resources/sql-tests/results/variant-field-extractions.sql.out
@@ -0,0 +1,343 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW variant_test_data AS
+SELECT
+  parse_json('{ "price": 30 }') as int_price_variant,
+  parse_json('{ "price": 12345.678 }') as double_price_variant,
+  parse_json('{ "name": "John", "age": 30, "city": "New York", "active": true, 
"scores": [85, 92, 78] }') as multi_field_variant,
+  parse_json('{ "item": [ { "model" : "basic", "price" : 6.12 }, { "model" : 
"medium", "price" : 9.24 } ] }') as array_value_variant,
+  parse_json('[{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }, { 
"id": 3, "name": "Charlie" }]') as array_variant,
+  parse_json('{ "metadata": { "version": "1.0", "tags": ["important", 
"urgent"], "nested": { "level": 2, "value": "deep" } } }') as nested_variant,
+  parse_json('{ "field-name": "value1", "field.name": "value2", "field_name": 
"value3" }') as special_chars_variant
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+select int_price_variant:price from variant_test_data
+-- !query schema
+struct<price:variant>
+-- !query output
+30
+
+
+-- !query
+select int_price_variant:price::decimal(5, 2) from variant_test_data
+-- !query schema
+struct<price:decimal(5,2)>
+-- !query output
+30.00
+
+
+-- !query
+select int_price_variant:price::string from variant_test_data
+-- !query schema
+struct<price:string>
+-- !query output
+30
+
+
+-- !query
+select double_price_variant:price::decimal(3, 2) from variant_test_data
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkRuntimeException
+{
+  "errorClass" : "INVALID_VARIANT_CAST",
+  "sqlState" : "22023",
+  "messageParameters" : {
+    "dataType" : "\"DECIMAL(3,2)\"",
+    "value" : "12345.678"
+  }
+}
+
+
+-- !query
+select multi_field_variant:name, multi_field_variant:age, 
multi_field_variant:city from variant_test_data
+-- !query schema
+struct<name:variant,age:variant,city:variant>
+-- !query output
+"John" 30      "New York"
+
+
+-- !query
+select multi_field_variant:name::string, multi_field_variant:age::int, 
multi_field_variant:active::boolean from variant_test_data
+-- !query schema
+struct<name:string,age:int,active:boolean>
+-- !query output
+John   30      true
+
+
+-- !query
+select multi_field_variant:['name'] from variant_test_data
+-- !query schema
+struct<name:variant>
+-- !query output
+"John"
+
+
+-- !query
+select multi_field_variant:['age'] from variant_test_data
+-- !query schema
+struct<age:variant>
+-- !query output
+30
+
+
+-- !query
+select array_value_variant:item[0].model from variant_test_data
+-- !query schema
+struct<model:variant>
+-- !query output
+"basic"
+
+
+-- !query
+select array_value_variant:item[0].price from variant_test_data
+-- !query schema
+struct<price:variant>
+-- !query output
+6.12
+
+
+-- !query
+select array_value_variant:item[1].model from variant_test_data
+-- !query schema
+struct<model:variant>
+-- !query output
+"medium"
+
+
+-- !query
+select array_value_variant:item[1].price from variant_test_data
+-- !query schema
+struct<price:variant>
+-- !query output
+9.24
+
+
+-- !query
+select array_variant:[0].id from variant_test_data
+-- !query schema
+struct<id:variant>
+-- !query output
+1
+
+
+-- !query
+select array_variant:[0].name from variant_test_data
+-- !query schema
+struct<name:variant>
+-- !query output
+"Alice"
+
+
+-- !query
+select array_variant:[1].id from variant_test_data
+-- !query schema
+struct<id:variant>
+-- !query output
+2
+
+
+-- !query
+select array_variant:[1].name from variant_test_data
+-- !query schema
+struct<name:variant>
+-- !query output
+"Bob"
+
+
+-- !query
+select nested_variant:metadata.version from variant_test_data
+-- !query schema
+struct<version:variant>
+-- !query output
+"1.0"
+
+
+-- !query
+select nested_variant:metadata.tags[0] from variant_test_data
+-- !query schema
+struct<tags:variant>
+-- !query output
+"important"
+
+
+-- !query
+select nested_variant:metadata.nested.level from variant_test_data
+-- !query schema
+struct<level:variant>
+-- !query output
+2
+
+
+-- !query
+select nested_variant:metadata.nested.value from variant_test_data
+-- !query schema
+struct<value:variant>
+-- !query output
+"deep"
+
+
+-- !query
+select nested_variant:metadata['version'] from variant_test_data
+-- !query schema
+struct<version:variant>
+-- !query output
+"1.0"
+
+
+-- !query
+select nested_variant:metadata['tags'] from variant_test_data
+-- !query schema
+struct<tags:variant>
+-- !query output
+["important","urgent"]
+
+
+-- !query
+select special_chars_variant:`field-name`::string from variant_test_data
+-- !query schema
+struct<field-name:string>
+-- !query output
+value1
+
+
+-- !query
+select special_chars_variant:['field-name']::string from variant_test_data
+-- !query schema
+struct<field-name:string>
+-- !query output
+value1
+
+
+-- !query
+select special_chars_variant:field_name::string from variant_test_data
+-- !query schema
+struct<field_name:string>
+-- !query output
+value3
+
+
+-- !query
+select special_chars_variant:['field_name']::string from variant_test_data
+-- !query schema
+struct<field_name:string>
+-- !query output
+value3
+
+
+-- !query
+select special_chars_variant:`field.name`::string from variant_test_data
+-- !query schema
+struct<name:string>
+-- !query output
+NULL
+
+
+-- !query
+select special_chars_variant:['field.name']::string from variant_test_data
+-- !query schema
+struct<field.name:string>
+-- !query output
+value2
+
+
+-- !query
+select multi_field_variant:scores[0]::int + multi_field_variant:scores[1]::int 
from variant_test_data
+-- !query schema
+struct<(CAST(variant_get(multi_field_variant, $.scores[0]) AS scores AS INT) + 
CAST(variant_get(multi_field_variant, $.scores[1]) AS scores AS INT)):int>
+-- !query output
+177
+
+
+-- !query
+select count(*) from (select explode(cast(multi_field_variant:scores as 
array<int>)) as score from variant_test_data)
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+3
+
+
+-- !query
+select * from variant_test_data
+-- !query schema
+struct<int_price_variant:variant,double_price_variant:variant,multi_field_variant:variant,array_value_variant:variant,array_variant:variant,nested_variant:variant,special_chars_variant:variant>
+-- !query output
+{"price":30}   {"price":12345.678}     {"active":true,"age":30,"city":"New 
York","name":"John","scores":[85,92,78]}    
{"item":[{"model":"basic","price":6.12},{"model":"medium","price":9.24}]}       
[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":3,"name":"Charlie"}]       
{"metadata":{"nested":{"level":2,"value":"deep"},"tags":["important","urgent"],"version":"1.0"}}
        {"field-name":"value1","field.name":"value2","field_name":"value3"}
+
+
+-- !query
+select multi_field_variant:* from variant_test_data
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'*'",
+    "hint" : ""
+  }
+}
+
+
+-- !query
+select typeof(multi_field_variant:name) from variant_test_data
+-- !query schema
+struct<typeof(variant_get(multi_field_variant, $.name) AS name):string>
+-- !query output
+variant
+
+
+-- !query
+select typeof(multi_field_variant:age) from variant_test_data
+-- !query schema
+struct<typeof(variant_get(multi_field_variant, $.age) AS age):string>
+-- !query output
+variant
+
+
+-- !query
+select typeof(multi_field_variant:active) from variant_test_data
+-- !query schema
+struct<typeof(variant_get(multi_field_variant, $.active) AS active):string>
+-- !query output
+variant
+
+
+-- !query
+select typeof(multi_field_variant:scores) from variant_test_data
+-- !query schema
+struct<typeof(variant_get(multi_field_variant, $.scores) AS scores):string>
+-- !query output
+variant
+
+
+-- !query
+select isnull(multi_field_variant:missing_field) from variant_test_data
+-- !query schema
+struct<(variant_get(multi_field_variant, $.missing_field) AS missing_field IS 
NULL):boolean>
+-- !query output
+true
+
+
+-- !query
+select isnotnull(multi_field_variant:name) from variant_test_data
+-- !query schema
+struct<(variant_get(multi_field_variant, $.name) AS name IS NOT NULL):boolean>
+-- !query output
+true
+
+
+-- !query
+select coalesce(multi_field_variant:missing_field, 'default_value') from 
variant_test_data
+-- !query schema
+struct<coalesce(variant_get(multi_field_variant, $.missing_field) AS 
missing_field, default_value):variant>
+-- !query output
+"default_value"
diff --git 
a/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ThriftServerQueryTestSuite.scala
 
b/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ThriftServerQueryTestSuite.scala
index 42e15b5ef559..047e4b8c9960 100644
--- 
a/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ThriftServerQueryTestSuite.scala
+++ 
b/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ThriftServerQueryTestSuite.scala
@@ -110,6 +110,7 @@ class ThriftServerQueryTestSuite extends SQLQueryTestSuite 
with SharedThriftServ
     "pipe-operators.sql",
     // VARIANT type
     "variant/named-function-arguments.sql",
+    "variant-field-extractions.sql",
     // SPARK-51516: Support the TIME data type by Thrift Server
     "time.sql"
   )
diff --git 
a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveSessionStateBuilder.scala
 
b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveSessionStateBuilder.scala
index 375eb55d2e48..89d34a3fa197 100644
--- 
a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveSessionStateBuilder.scala
+++ 
b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveSessionStateBuilder.scala
@@ -28,7 +28,7 @@ import org.apache.spark.sql.AnalysisException
 import org.apache.spark.sql.catalyst.analysis.{Analyzer, 
EvalSubqueriesForTimeTravel, InvokeProcedures, ReplaceCharWithVarchar, 
ResolveDataSource, ResolveSessionCatalog, ResolveTranspose}
 import org.apache.spark.sql.catalyst.analysis.resolver.ResolverExtension
 import org.apache.spark.sql.catalyst.catalog.{ExternalCatalogWithListener, 
InvalidUDFClassException}
-import org.apache.spark.sql.catalyst.expressions.Expression
+import org.apache.spark.sql.catalyst.expressions.{Expression, 
ExtractSemiStructuredFields}
 import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
 import org.apache.spark.sql.catalyst.rules.Rule
 import org.apache.spark.sql.classic.{SparkSession, Strategy}
@@ -133,6 +133,7 @@ class HiveSessionStateBuilder(
         new DetermineTableStats(session) +:
         new ResolveTranspose(session) +:
         new InvokeProcedures(session) +:
+        ExtractSemiStructuredFields +:
         customResolutionRules
 
     override val postHocResolutionRules: Seq[Rule[LogicalPlan]] =


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to