Repository: tobymao/sqlglot

Issue:
exp.JsonExtract will got a warning log in Starrocks
Ways to use:
sqlglot.transpile(sql, read="starrocks", write="starrocks")

**Fully reproducible code snippet**
```
select cast(parse_json(fieldvalue) -> '00000000-0000-0000-0000-00000000' as varchar ) as `code` from values('{"00000000-0000-0000-0000-00000000":"code01"}') as t(fieldvalue)
```
It will got a warnning log as following:
Invalid JSON path syntax. Unexpected TokenType.NUMBER at index 0: 00000000-0000-0000-0000-00000000

Then I tried to transpile spark to spark, which worked fine:
> sqlglot.transpile(sql, read="spark", write="spark")
```
SELECT CAST(PARSE_JSON(fieldvalue)['00000000-0000-0000-0000-00000000'] AS STRING) AS `code` FROM VALUES ('{"00000000-0000-0000-0000-00000000":"code01"}') AS t(fieldvalue)
```
It doesn't look like normal behavior, please help me.
Thank you! 



Discussion:

Patch:
diff --git a/sqlglot/dialects/dialect.py b/sqlglot/dialects/dialect.py
index bc8fecbf..294a329f 100644
--- a/sqlglot/dialects/dialect.py
+++ b/sqlglot/dialects/dialect.py
@@ -388,6 +388,9 @@ class Dialect(metaclass=_Dialect):
     dialects which don't support fixed size arrays such as Snowflake, this should be interpreted as a subscript/index operator
     """
 
+    STRICT_JSON_PATH_SYNTAX = True
+    """Whether failing to parse a JSON path expression using the JSONPath dialect will log a warning."""
+
     SET_OP_DISTINCT_BY_DEFAULT: t.Dict[t.Type[exp.Expression], t.Optional[bool]] = {
         exp.Except: True,
         exp.Intersect: True,
@@ -898,7 +901,8 @@ class Dialect(metaclass=_Dialect):
             try:
                 return parse_json_path(path_text, self)
             except ParseError as e:
-                logger.warning(f"Invalid JSON path syntax. {str(e)}")
+                if self.STRICT_JSON_PATH_SYNTAX:
+                    logger.warning(f"Invalid JSON path syntax. {str(e)}")
 
         return path
 
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
index 22315054..f39b5fd4 100644
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -263,6 +263,7 @@ class DuckDB(Dialect):
     CONCAT_COALESCE = True
     SUPPORTS_ORDER_BY_ALL = True
     SUPPORTS_FIXED_SIZE_ARRAYS = True
+    STRICT_JSON_PATH_SYNTAX = False
 
     # https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
     NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
diff --git a/sqlglot/dialects/mysql.py b/sqlglot/dialects/mysql.py
index 5dde49ae..eff42389 100644
--- a/sqlglot/dialects/mysql.py
+++ b/sqlglot/dialects/mysql.py
@@ -707,7 +707,7 @@ class MySQL(Dialect):
         JSON_PATH_BRACKETED_KEY_SUPPORTED = False
         JSON_KEY_VALUE_PAIR_SEP = ","
         SUPPORTS_TO_NUMBER = False
-        PARSE_JSON_NAME = None
+        PARSE_JSON_NAME: t.Optional[str] = None
         PAD_FILL_PATTERN_IS_REQUIRED = True
         WRAP_DERIVED_VALUES = False
 
diff --git a/sqlglot/dialects/starrocks.py b/sqlglot/dialects/starrocks.py
index d20c08b6..da0d28fb 100644
--- a/sqlglot/dialects/starrocks.py
+++ b/sqlglot/dialects/starrocks.py
@@ -16,6 +16,8 @@ from sqlglot.helper import seq_get
 
 
 class StarRocks(MySQL):
+    STRICT_JSON_PATH_SYNTAX = False
+
     class Parser(MySQL.Parser):
         FUNCTIONS = {
             **MySQL.Parser.FUNCTIONS,
@@ -50,6 +52,8 @@ class StarRocks(MySQL):
 
     class Generator(MySQL.Generator):
         EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE = False
+        JSON_TYPE_REQUIRED_FOR_EXTRACTION = False
+        PARSE_JSON_NAME: t.Optional[str] = "PARSE_JSON"
 
         CAST_MAPPING = {}
 


Test patch:
diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
index b002188b..7d2eb56f 100644
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -1408,6 +1408,13 @@ class TestDialect(Validator):
             },
         )
 
+        for dialect in ("duckdb", "starrocks"):
+            with self.subTest(f"Generating json extraction with digit-prefixed key ({dialect})"):
+                self.assertEqual(
+                    parse_one("""select '{"0": "v"}' -> '0'""", read=dialect).sql(dialect=dialect),
+                    """SELECT '{"0": "v"}' -> '0'""",
+                )
+
     def test_cross_join(self):
         self.validate_all(
             "SELECT a FROM x CROSS JOIN UNNEST(y) AS t (a)",
diff --git a/tests/dialects/test_starrocks.py b/tests/dialects/test_starrocks.py
index 476bea4a..5ada1668 100644
--- a/tests/dialects/test_starrocks.py
+++ b/tests/dialects/test_starrocks.py
@@ -8,6 +8,9 @@ class TestStarrocks(Validator):
         self.validate_identity("SELECT CAST(`a`.`b` AS INT) FROM foo")
         self.validate_identity("SELECT APPROX_COUNT_DISTINCT(a) FROM x")
         self.validate_identity("SELECT [1, 2, 3]")
+        self.validate_identity(
+            """SELECT CAST(PARSE_JSON(fieldvalue) -> '00000000-0000-0000-0000-00000000' AS VARCHAR) AS `code` FROM (SELECT '{"00000000-0000-0000-0000-00000000":"code01"}') AS t(fieldvalue)"""
+        )
 
     def test_time(self):
         self.validate_identity("TIMESTAMP('2022-01-01')")