{"id":21069276,"url":"https://github.com/starlake-ai/jsqltranspiler","last_synced_at":"2025-08-06T10:32:41.566Z","repository":{"id":243902468,"uuid":"780859552","full_name":"starlake-ai/jsqltranspiler","owner":"starlake-ai","description":"Rewrite BigQuery, Redshift, Snowflake and Databricks queries into DuckDB compatible SQL (with deep transformation of functions, data types and format characters) using Java.","archived":false,"fork":false,"pushed_at":"2025-08-06T03:43:17.000Z","size":13292,"stargazers_count":56,"open_issues_count":20,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-08-06T05:26:02.147Z","etag":null,"topics":["abstract-syntax-tree","bigquery","column","databricks","duckdb","java","lineage","query","redshift","resolver","rewrite","snowflake","transpiler"],"latest_commit_sha":null,"homepage":"https://starlake.ai/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/starlake-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-04-02T09:46:05.000Z","updated_at":"2025-08-06T03:43:21.000Z","dependencies_parsed_at":"2024-06-12T00:16:22.821Z","dependency_job_id":"1ffd801e-9d8e-4cb4-a80c-ac1aac70b583","html_url":"https://github.com/starlake-ai/jsqltranspiler","commit_stats":null,"previous_names":["starlake-ai/jsqltranspiler"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/starlake-ai/jsqltranspiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starlake-ai%2Fjsqltranspiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starlake-ai%2Fjsqltranspiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starlake-ai%2Fjsqltranspiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starlake-ai%2Fjsqltranspiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/starlake-ai","download_url":"https://codeload.github.com/starlake-ai/jsqltranspiler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starlake-ai%2Fjsqltranspiler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269027515,"owners_count":24347258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-06T02:00:09.910Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstract-syntax-tree","bigquery","column","databricks","duckdb","java","lineage","query","redshift","resolver","rewrite","snowflake","transpiler"],"created_at":"2024-11-19T18:34:00.031Z","updated_at":"2025-08-06T10:32:41.552Z","avatar_url":"https://github.com/starlake-ai.png","language":"Java","funding_links":[],"categories":["Libraries Powered by DuckDB"],"sub_categories":[],"readme":"# [JSQLTranspiler](https://starlake.ai/starlake/index.html#sql-transpiler) - Transpile Dialect, Resolve Columns, Show Lineage, Refactor Queries\n\n[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/ai.starlake.jsqltranspiler/jsqltranspiler?server=https%3A%2F%2Fs01.oss.sonatype.org)](https://s01.oss.sonatype.org/#nexus-search;quick~ai.starlake.jsqltranspiler/jsqltranspiler)\n[![JavaDoc](https://javadoc.io/badge2/ai.starlake.jsqltranspiler/jsqltranspiler/javadoc.svg)](https://javadoc.io/doc/ai.starlake.jsqltranspiler/jsqltranspiler)\n[![Gradle CI](https://github.com/starlake-ai/jsqltranspiler/actions/workflows/snapshot.yml/badge.svg)](https://github.com/starlake-ai/jsqltranspiler/actions/workflows/snapshot.yml)\n[![Code Quality](https://app.codacy.com/project/badge/Grade/80374649d914462ebd6e5b160a1ebdbb)](https://app.codacy.com/gh/starlake-ai/jsqltranspiler/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n[![Coverage](https://coveralls.io/repos/github/starlake-ai/jsqltranspiler/badge.svg)](https://coveralls.io/github/starlake-ai/jsqltranspiler)\n[![License](https://img.shields.io/badge/License-Apache-blue)](#LICENSE)\n[![Issues](https://img.shields.io/github/issues/starlake-ai/jsqltranspiler)](https://github.com/starlake-ai/jsqltranspiler/issues)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github?af=5236ad)\n\nA pure Java stand-alone SQL Transpiler, Column- and Lineage Resolver for translating various large RDBMS SQL Dialects into a few smaller RDBMS Dialects for Unit Testing. Based on JSQLParser.\n\nSupports `SELECT` queries as well as `INSERT`, `UPDATE`, `DELETE` and `MERGE` statements.\n\nInternal Functions will be rewritten based on the actual meaning and purpose of the function (since the DuckDB `Any()` function does not necessarily behave like the RDBMS specific `Any()`). Respecting different function arguments count, order and type.\n\nRewrite of Window- and Aggregate-Functions with full coverage of the RDBMS specific published samples.\nThe [matrix of supported features and functions](https://docs.google.com/spreadsheets/d/1jK6E1s2c0CWcw9rFeDvALdZ5wCshztdtlAHuNDaKQt4/edit?usp=sharing) is shared on Google Sheets.\n\n## Dialects\n\n**Input**: Google BigQuery, Databricks, Snowflake, Amazon Redshift\n\n**Output**: DuckDB\n\n## Transpile Example\n\nGoogle BigQuery specific SQL\n\n```sql\n-- BigQuery specific DATE() function\nSELECT\n  DATE(2016, 12, 25) AS date_ymd,\n  DATE(DATETIME '2016-12-25 23:59:59') AS date_dt,\n  DATE(TIMESTAMP '2016-12-25 05:30:00+07', 'America/Los_Angeles') AS date_tstz;\n\n/* Output\n\"date_ymd\",\"date_dt\",\"date_tstz\"\n\"2016-12-15\",\"2016-12-15\",\"2016-12-15\"\n*/\n```\n\nwill become DuckDB compatible SQL\n\n```sql\n-- DuckDB compliant rewrite producing the same result\nSELECT\n  MAKE_DATE(2016, 12, 25) AS date_ymd,\n  CAST(DATETIME '2016-12-25 23:59:59' AS DATE) AS date_dt,\n  CAST(TIMESTAMP '2016-12-25 05:30:00+07' AS DATE) AS date_tstz;\n\n/* Output\n\"date_ymd\",\"date_dt\",\"date_tstz\"\n\"2016-12-15\",\"2016-12-15\",\"2016-12-15\"\n*/\n```\n\n## Column Lineage Example\nFor the simplified schema definition and the given query\n```java\nString[][] schemaDefinition = {\n        // Table A with Columns col1, col2, col3, colAA, colAB\n        {\"a\", \"col1\", \"col2\", \"col3\", \"colAA\", \"colAB\"},\n\n        // Table B with Columns col1, col2, col3, colBA, colBB\n        {\"b\", \"col1\", \"col2\", \"col3\", \"colBA\", \"colBB\"}\n};\n\nString sqlStr =\n        \"SELECT Case when Sum(colBA + colBB)=0 then c.col1 else a.col2 end AS total FROM a INNER JOIN (SELECT * FROM b) c ON a.col1 = c.col1\";\n\nJdbcResultSetMetaData resultSetMetaData = new JSQLColumResolver(databaseMetaData).getResultSetMetaData(sqlStr);\n```\n\nthe ResultSetMetaData return a list of JdbcColumns, each traversable using the `TreeNode` interface. The resulting Column Lineage can be illustrated as:\n```\nSELECT\n └─total AS CaseExpression: CASE WHEN Sum(colBA + colBB) = 0 THEN c.col1 ELSE a.col2 END\n    ├─WhenClause: WHEN Sum(colBA + colBB) = 0 THEN c.col1\n    │  ├─EqualsTo: Sum(colBA + colBB) = 0\n    │  │  └─Function: Sum(colBA + colBB)\n    │  │     └─Addition: colBA + colBB\n    │  │        ├─c.colBA → b.colBA : Other\n    │  │        └─c.colBB → b.colBB : Other\n    │  └─c.col1 → b.col1 : Other\n    └─a.col2 : Other\n```\n\n\n## Resolve ``*`` Star Operator Example\n\nFor the simplified schema definition and the given query with Star Operators\n```java\nString[][] schemaDefinition = {\n    // Table A with Columns col1, col2, col3, colAA, colAB\n    {\"a\", \"col1\", \"col2\", \"col3\", \"colAA\", \"colAB\"},\n\n    // Table B with Columns col1, col2, col3, colBA, colBB\n    {\"b\", \"col1\", \"col2\", \"col3\", \"colBA\", \"colBB\"}\n};\n\nString sqlStr = \"SELECT * FROM ( (SELECT * FROM b) c inner join a on c.col1 = a.col1 ) d;\";\nString resolved =  new JSQLColumResolver(schemaDefinition).getResolvedStatementText(sqlStr);\n```\n\nthe query will be resolved and (optionally rewritten into):\n```sql\nSELECT  d.col1                 /* Resolved Column*/\n        , d.col2               /* Resolved Column*/\n        , d.col3               /* Resolved Column*/\n        , d.colBA              /* Resolved Column*/\n        , d.colBB              /* Resolved Column*/\n        , d.col1_1             /* Resolved Column*/\n        , d.col2_1             /* Resolved Column*/\n        , d.col3_1             /* Resolved Column*/\n        , d.colAA              /* Resolved Column*/\n        , d.colAB              /* Resolved Column*/\nFROM (  (   SELECT  b.col1     /* Resolved Column*/\n                    , b.col2   /* Resolved Column*/\n                    , b.col3   /* Resolved Column*/\n                    , b.colba  /* Resolved Column*/\n                    , b.colbb  /* Resolved Column*/\n            FROM b ) c\n            INNER JOIN a\n                ON c.col1 = a.col1 ) d\n;\n```\n\nAlternatively, the information about returned columns can be fetched as JDBC `ResultsetMetaData` (without actually executing this query):\n\n```java\nimport java.sql.DatabaseMetaData;\n\nString sqlStr = \"SELECT * FROM (  (  SELECT * FROM sales ) c INNER JOIN listing a ON c.listid = a.listid ) d;\";\n// the meta data of catalgogs, schemas, tables, columns, either virtually and physically\nDatabaseMetaData databaseMetaData = ...;\nResultSetMetaData resultSetMetaData = new JSQLColumResolver(databaseMetaData).getResultSetMetaData(sqlStr);\nSystem.out.println(resultSetMetaData.toString());\n\n/*\n\"#\",\"label\",\"name\",\"table\",\"schema\",\"catalog\",\"type\",\"type name\",\"precision\",\"scale\",\"display size\"\n\"1\",\"salesid\",\"salesid\",\"d\",,\"JSQLTranspilerTest\",\"INTEGER\",\"INTEGER\",\"0\",\"32\",\"0\"\n\"2\",\"listid\",\"listid\",\"d\",,\"JSQLTranspilerTest\",\"INTEGER\",\"INTEGER\",\"0\",\"32\",\"0\"\n... (shortened) ...\n\"17\",\"totalprice\",\"totalprice\",\"d\",,\"JSQLTranspilerTest\",\"DECIMAL\",\"DECIMAL(8,2)\",\"0\",\"8\",\"0\"\n\"18\",\"listtime\",\"listtime\",\"d\",,\"JSQLTranspilerTest\",\"TIMESTAMP\",\"TIMESTAMP\",\"0\",\"0\",\"0\"\n */\n\n```\n\n## PipedSQL Example\n\nPiped SQL is a much saner and more logical way to write queries in its semantic order.\n```sql\nFROM Produce\n|\u003e WHERE\n    item != 'bananas'\n    AND category IN ('fruit', 'nut')\n|\u003e AGGREGATE COUNT(*) AS num_items, SUM(sales) AS total_sales\n   GROUP BY item\n|\u003e ORDER BY item DESC;\n```\n\nFor details, please see https://storage.googleapis.com/gweb-research2023-media/pubtools/1004848.pdf,  https://cloud.google.com/bigquery/docs/reference/standard-sql/pipe-syntax and https://duckdb.org/docs/sql/query_syntax/from.html#from-first-syntax\n\nJSQLTranspiler can rewrite PipedSQL into regular SQL, which can be executed on any normal RDBMS.\n\n```java\nString sql =\n            \"(\\n\" +\n            \"  SELECT '000123' AS id, 'apples' AS item, 2 AS sales\\n\" +\n            \"  UNION ALL\\n\" +\n            \"  SELECT '000456' AS id, 'bananas' AS item, 5 AS sales\\n\" +\n            \") AS sales_table\\n\" +\n            \"|\u003e AGGREGATE SUM(sales) AS total_sales GROUP BY id, item\\n\" +\n            \"|\u003e AS t1\\n\" +\n            \"|\u003e JOIN (SELECT 456 AS id, 'yellow' AS color) AS t2\\n\" +\n            \"   ON CAST(t1.id AS INT64) = t2.id\\n\" +\n            \"|\u003e SELECT t2.id, total_sales, color;\";\n\n    try (Statement st = connDuck.createStatement();\n         ResultSet rs = st.executeQuery( JSQLTranspiler.transpileQuery(sql, JSQLTranspiler.Dialect.ANY) );\n    ) {\n      ResultSetMetaData resultSetMetaData = rs.getMetaData();\n      Assertions.assertEquals(3, resultSetMetaData.getColumnCount());\n      Assertions.assertEquals( \"id\", resultSetMetaData.getColumnLabel(1));\n      Assertions.assertEquals( \"total_sales\", resultSetMetaData.getColumnLabel(2));\n      Assertions.assertEquals( \"color\", resultSetMetaData.getColumnLabel(3));\n\n      Assertions.assertTrue( rs.next() );\n      Assertions.assertEquals(456, rs.getInt(1) );\n      Assertions.assertEquals(5, rs.getInt(2) );\n      Assertions.assertEquals(\"yellow\", rs.getString(3) );\n    }\n```\n\n## SQL Refactoring example\n\n`JSQLTranspiler` can refactor statements by replacing table names. The following example swaps the tablenames `a` and `b` in a query based on the physical tables of the given metadata:\n\n```sql\n-- Input:\nSELECT a.*\nFROM (  SELECT  a.col3\n                , Sum( a.col2 )\n        FROM a inner join b on a.col1=b.col1\n        WHERE a.col1 = b.col1\n        GROUP BY a.col3\n        HAVING Sum( a.col2 ) \u003e 0 ) AS a\n;\n```\n\n```java\nJSQLReplacer replacer = new JSQLReplacer({{\"a\", \"col1\", \"col2\", \"col3\"}, {\"b\", \"col1\", \"col2\", \"col3\"}});\nreplacer.replace(sqlStr, Map.of(\"a\", \"b\", \"b\", \"a\"));\n```    \n\n```sql\n-- Output:\nSELECT  a.col3\n        , a.sum\nFROM (  SELECT  b.col3\n                , Sum( b.col2 )\n        FROM b\n            INNER JOIN a\n                ON b.col1 = a.col1\n        WHERE b.col1 = a.col1\n        GROUP BY b.col3\n        HAVING Sum( b.col2 ) \u003e 0 ) AS a;\n;\n```\n\n\n## How to use\n\n### Java Library\n\nMaven Artifact with Snapshot support:\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003ejsqltranspiler-snapshots\u003c/id\u003e\n        \u003csnapshots\u003e\n            \u003cenabled\u003etrue\u003c/enabled\u003e\n        \u003c/snapshots\u003e\n        \u003curl\u003ehttps://s01.oss.sonatype.org/content/repositories/snapshots/\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eai.starlake.jsqltranspiler\u003c/groupId\u003e\n    \u003cartifactId\u003ejsqltranspiler\u003c/artifactId\u003e\n    \u003cversion\u003e0.7-SNAPSHOT\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nCalling the Java class:\n```java\nimport ai.starlake.transpiler.JSQLTranspiler;\n\nString providedSQL=\"SELECT Nvl(null, 1) a\";\nString expectedSQL=\"SELECT Coalesce(null, 1) a\";\n\nString result = JSQLTranspiler.transpile(providedSQL, Dialect.AMAZON_REDSHIFT);\nassertEquals(expectedSQL, result);\n```\n\n### Web API\n```shell\ncurl -X 'POST'                                                                   \\\n  'https://app.starlake.ai/api/v1/transpiler/transpile?dialect=SNOWFLAKE'            \\\n  -H 'accept: text/plain'                                                        \\\n  -H 'Content-Type: text/plain'                                                  \\\n  -d 'SELECT Nvl(null, 1) a'\n```\n\n### Java Command Line Interface\n```text\nusage: java -jar JSQLTranspilerCLI.jar [-d \u003carg\u003e | --any | --bigquery |\n       --databricks | --snowflake | --redshift]      [-D \u003carg\u003e | --duckdb]\n       [-i \u003carg\u003e] [-o \u003carg\u003e] [-h]\n\n -d,--input-dialect \u003carg\u003e    The SQL dialect to parse.\n                             [ANY*, GOOGLE_BIG_QUERY, DATABRICKS,\n                             SNOWFLAKE, AMAZON_REDSHIFT]\n    --any                    Interpret the SQL as Generic Dialect\n                             [DEFAULT].\n    --bigquery               Interpret the SQL as Google BigQuery Dialect.\n    --databricks             Interpret the SQL as DataBricks Dialect.\n    --snowflake              Interpret the SQL as Snowflake Dialect.\n    --redshift               Interpret the SQL as Amazon Snowflake\n                             Dialect.\n -D,--output-dialect \u003carg\u003e   The SQL dialect to write.\n                             [DUCKDB*]\n    --duckdb                 Write the SQL in the Duck DB Dialect\n                             [DEFAULT].\n -i,--inputFile \u003carg\u003e        The input SQL file or folder.\n                             - Read from STDIN when no input file\n                             provided.\n -o,--outputFile \u003carg\u003e       The out SQL file for the formatted\n                             statements.\n                             - Create new SQL file when folder provided.\n                             - Append when existing file provided.\n                             - Write to STDOUT when no output file\n                             provided.\n -h,--help                   Print the help synopsis.\n```\n\n### TimeKey substitution\n\nThe transpiler can substitute time key expressions such as `CURRENT_DATE` or `CURRENT_TIMESTAMP` with System's properties like\n\n```java\nSystem.setProperty(\"CURRENT_TIMESTAMP\", \"2024-06-09 16:24:23.123\");\nString expected = \"SELECT TIMESTAMP WITHOUT TIME ZONE '2024-06-09T16:24:23.123'\";\nString actual = JSQLTranspiler.transpileQuery(\"SELECT CURRENT_TIMESTAMP\", JSQLTranspiler.Dialect.ANY);\n\nAssertions.assertThat(actual).isEqualTo(expected);\n```\n\nAlternatively parameters can be provided as `Map\u003cString,Object\u003e` (which would take precedence over any System's properties):\n\n```java\nString expected = \"SELECT TIME WITHOUT TIME ZONE '17:24:23.123'\";\nString actual =\n        JSQLTranspiler.transpileQuery(\n                \"SELECT CURRENT_TIME\"\n                , JSQLTranspiler.Dialect.ANY\n                , Map.of(\"CURRENT_TIME\", \"17:24:23.123\")\n        );\n\nAssertions.assertThat(actual).isEqualTo(expected);\n```\n\n### Geography vs. Geometry\n\nDuckDB currently only supports the `GEOMETRY` type. So for overloaded functions we need to decide if to interpret as `GEOMETRY` or as `GEOGRAPHY`. One can use the property `GEO_MODE` and set it either to `GEOGRAPHY` or `GEOMETRY` (with `GEOMETRY` being the default). Alternatively the Parameter Map can be used.\n\n```java\nString expected = \"SELECT ST_Area_Spheroid(ST_GEOMFROMTEXT('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) AS area\";\nString actual = JSQLTranspiler\n                    .transpileQuery(\n                            \"select st_area(ST_GEOGFROMTEXT('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) as area;\"\n                            , JSQLTranspiler.Dialect.GOOGLE_BIG_QUERY\n                            , Map.of(\"GEO_MODE\", \"GEOGRAPHY\")\n                    );\nAssertions.assertEquals(expected, actual);\nAssertions.assertEquals(12308778361.469452, getQueryResults(actual)[1][0]);\n```\n\n```java\nSystem.setProperty(\"GEO_MODE\", \"GEOMETRY\");\nString expected = \"SELECT ST_Area(ST_GEOMFROMTEXT('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) AS area\";\nString actual = JSQLTranspiler\n                    .transpileQuery(\n                            \"select ST_Area(ST_GEOGFROMTEXT('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')) as area;\"\n                            , JSQLTranspiler.Dialect.GOOGLE_BIG_QUERY\n                    );\nAssertions.assertEquals(expected, actual);\nAssertions.assertEquals(1.0, getQueryResults(actual)[1][0]);\n```\n\n### Error Handling\n\nIn case the query refers to objects not existing in the provided database schema, the `JSQLColumnResolver` offers three modes:\n\n- `STRICT` will let the resolution and lineage fail with an error message, which (first) object were not resolved\n- `IGNORE` will simply ignore the node of the unresolvable object\n- `LENIENT` will insert a \"virtual\" column node pointing on the unresolvable column of an unknown type\n\n`STRICT` is the default error mode. It can be changed for the `JdbcMetaData` before passing it to the `JSQLColumnResolver` as shown in the code example below:\n\n```java\n\nString sqlStr =\n            \"with \\\"mycte\\\" as (\\n\"\n            + \"    select invalidColumn, \\\"c\\\".\\\"id\\\", CURRENT_TIMESTAMP() as \\\"timestamp\\\"\\n\"\n            + \"    from nonExistingTable \\\"o\\\", \\\"sales\\\".\\\"customers\\\" \\\"c\\\"\\n\"\n            + \"    where \\\"o\\\".\\\"customer_id\\\" = \\\"c\\\".\\\"id\\\"\\n\"\n            + \")\\n\"\n            + \"select \\\"id\\\", sum(\\\"amount\\\") as sum, \\\"timestamp\\\"\\n\"\n            + \"from \\\"mycte\\\"\\n\"\n            + \"group by \\\"mycte\\\".\\\"id\\\", \\\"mycte\\\".\\\"timestamp\\\"\";\n\n// STRICT MODE will throw an Exception\nResultSetMetaData res =\n        JSQLColumResolver.getResultSetMetaData(sqlStr, JdbcMetaData.copyOf(metaData.setErrorMode(JdbcMetaData.ErrorMode.STRICT)));\n\n// LENIENT MODE will show an unresolvable node\nResultSetMetaData res =\n        JSQLColumResolver.getResultSetMetaData(sqlStr, JdbcMetaData.copyOf(metaData.setErrorMode(JdbcMetaData.ErrorMode.LENIENT)));\nString lineage =\n        \"SELECT\\n\"\n        + \" ├─mycte.id → sales.customers.id : Other\\n\"\n        + \" ├─sum AS Function sum\\n\"\n        + \" │  └─unresolvable\\n\"\n        + \" └─mycte.timestamp → timestamp : Other\\n\";\n\n// IGNORE will skip and supress the unresolvable node\nResultSetMetaData res =\n        JSQLColumResolver.getResultSetMetaData(sqlStr, JdbcMetaData.copyOf(metaData.setErrorMode(JdbcMetaData.ErrorMode.IGNORE)));\nString lineage =\n        \"SELECT\\n\"\n        + \" ├─mycte.id → sales.customers.id : Other\\n\"\n        + \" ├─sum AS Function sum\\n\"\n        + \" └─mycte.timestamp → timestamp : Other\\n\";\n```\n[More Details at JSQLColumnResolverTest](https://github.com/starlake-ai/jsqltranspiler/blob/f964a3e69e583abb637baa569cf96dd4b0350043/src/test/java/ai/starlake/transpiler/JSQLColumnResolverTest.java#L590)\n\n\n### Unsupported features\n\nPlease refer to the [Feature Matrix](https://docs.google.com/spreadsheets/d/1jK6E1s2c0CWcw9rFeDvALdZ5wCshztdtlAHuNDaKQt4/edit?usp=sharing):\n\n- DuckDB's Number and Currency formatting is very limited right now\n- `SELECT * REPLACE(...)` on DuckDB works very differently (replaces value instead of label)\n\n## License\n\n**JSQLTranspiler** is licensed under [**Apache License, Version 2.0**](https://www.apache.org/licenses/LICENSE-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarlake-ai%2Fjsqltranspiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstarlake-ai%2Fjsqltranspiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarlake-ai%2Fjsqltranspiler/lists"}