Skip to content

Commit 3f9c7b3

Browse files
Merge pull request #2026 from taozhi8833998/feat-exclude-column-snowflake
feat: support * exclude columns in snowflake
2 parents 13c875f + 12ee83f commit 3f9c7b3

File tree

3 files changed

+61
-41
lines changed

3 files changed

+61
-41
lines changed

pegjs/snowflake.pegjs

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,23 +2168,25 @@ query_option
21682168
return option;
21692169
}
21702170

2171+
column_star_option
2172+
= 'exclude'i __ LPAREN __ l:expr_list __ RPAREN {
2173+
return {
2174+
type: 'function',
2175+
name: { name: [{ type: 'origin', value: 'exclude' }] },
2176+
args: l,
2177+
};
2178+
}
2179+
/ 'exclude'i __ c:column_ref {
2180+
return {
2181+
type: 'function',
2182+
name: { name: [{ type: 'origin', value: 'exclude' }] },
2183+
args:{ type: 'expr_list', value: [c] },
2184+
args_parentheses: false,
2185+
};
2186+
}
2187+
21712188
column_clause
2172-
= head: (KW_ALL / (STAR !ident_start) / STAR) tail:(__ COMMA __ column_list_item)* {
2173-
// => 'ALL' | '*' | column_list_item[]
2174-
columnList.add('select::null::(.*)')
2175-
const item = {
2176-
expr: {
2177-
type: 'column_ref',
2178-
table: null,
2179-
column: '*'
2180-
},
2181-
as: null,
2182-
...getLocationObject()
2183-
}
2184-
if (tail && tail.length > 0) return createList(item, tail)
2185-
return [item]
2186-
}
2187-
/ head:column_list_item tail:(__ COMMA __ column_list_item)* {
2189+
= head:column_list_item tail:(__ COMMA __ column_list_item)* {
21882190
// => column_list_item[]
21892191
return createList(head, tail);
21902192
}
@@ -2226,7 +2228,21 @@ cast_data_type
22262228
}
22272229

22282230
column_list_item
2229-
= c:string_constants_escape {
2231+
= head: (KW_ALL / STAR) __ c:column_star_option? {
2232+
// => 'ALL' | '*' | column_list_item[]
2233+
columnList.add('select::null::(.*)')
2234+
return {
2235+
expr: {
2236+
type: 'column_ref',
2237+
table: null,
2238+
column: '*',
2239+
suffix: c,
2240+
},
2241+
as: null,
2242+
...getLocationObject()
2243+
}
2244+
}
2245+
/ c:string_constants_escape {
22302246
// => { expr: expr; as: null; }
22312247
return { expr: c, as: null, ...getLocationObject(), }
22322248
}
@@ -2242,41 +2258,31 @@ column_list_item
22422258
...getLocationObject(),
22432259
}
22442260
}
2245-
/ tbl:ident __ DOT pro:(ident __ DOT)? __ STAR {
2261+
/ tbl:(ident __ DOT)? pro:(ident __ DOT)? __ (KW_ALL/STAR) __ c:column_star_option? {
22462262
// => { expr: column_ref; as: null; }
2247-
const mid = pro && pro[0]
2248-
let schema
2249-
if (mid) {
2250-
schema = tbl
2251-
tbl = mid
2263+
let schema, table
2264+
if (tbl) {
2265+
schema = null
2266+
table = tbl[0]
22522267
}
2253-
columnList.add(`select::${tbl}::(.*)`)
2268+
if (pro) {
2269+
schema = tbl[0]
2270+
table = pro[0]
2271+
}
2272+
columnList.add(`select::${table}::(.*)`)
22542273
const column = '*'
22552274
return {
22562275
expr: {
22572276
type: 'column_ref',
2258-
table: tbl,
2277+
table,
22592278
schema,
22602279
column,
2280+
suffix: c,
22612281
},
22622282
as: null,
22632283
...getLocationObject()
22642284
}
22652285
}
2266-
/ tbl:(ident __ DOT)? __ STAR {
2267-
// => { expr: column_ref; as: null; }
2268-
const table = tbl && tbl[0] || null
2269-
columnList.add(`select::${table}::(.*)`);
2270-
return {
2271-
expr: {
2272-
type: 'column_ref',
2273-
table: table,
2274-
column: '*'
2275-
},
2276-
as: null,
2277-
...getLocationObject()
2278-
};
2279-
}
22802286
/ c:double_quoted_ident __ d:DOT? !{ if(d) return true } __ alias: alias_clause? {
22812287
// => { type: 'expr'; expr: expr; as?: alias_clause; }
22822288
columnList.add(`select::null::${c.value}`)

src/column.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function columnRefToSQL(expr) {
5454
commonOptionConnector('AS', exprToSQL, as),
5555
jsonOrJsonbToSQL(jsonb),
5656
]
57-
result.push(toUpper(suffix))
57+
result.push(typeof suffix === 'string' ? toUpper(suffix) : exprToSQL(suffix))
5858
result.push(toUpper(order_by))
5959
const sql = result.filter(hasVal).join(' ')
6060
return parentheses ? `(${sql})` : sql

test/snowflake.spec.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,21 @@ describe('snowflake', () => {
375375
unpivot(transaction_amount_usd FOR transaction_type IN (Charge, Taxes_and_Fees)))))`,
376376
`SELECT "transaction_date", "platform", "date_granularity", "transaction_type", "buyer_country", "sku", "transaction_currency", "exchange_rate", "transaction_amount_usd", "transaction_amount_local_currency", "transaction_amount_ils" FROM ((SELECT 'android' AS "platform", 'Daily' AS "date_granularity", "transaction_date", "transaction_type", "buyer_country", "sku", "transaction_currency", "exchange_rate", SUM("transaction_amount_usd") AS "transaction_amount_usd", SUM("transaction_amount_local_currency") AS "transaction_amount_local_currency", SUM("amount_merchant_currency") AS "transaction_amount_ils" FROM (SELECT to_date("ge"."transaction_date", 'Mon DD, YYYY') AS "transaction_date", "ge"."transaction_type" AS "transaction_type", "ge"."product_title" AS "product", "ge"."sku_id" AS "sku", "ge"."buyer_country" AS "buyer_country", "ge"."buyer_currency" AS "transaction_currency", "er"."rate" AS "exchange_rate", "ge"."amount_buyer_currency" AS "transaction_amount_local_currency", "ge"."amount_buyer_currency" / "er"."rate" AS "transaction_amount_usd", "ge"."amount_merchant_currency" AS "amount_merchant_currency" FROM (SELECT DISTINCT * FROM "staging"."raw"."google_play_store_earnings") AS "ge" INNER JOIN "F_EXCHANGE_RATES" AS "er" ON date("er"."time") = to_date("ge"."transaction_date", 'Mon DD, YYYY') AND "er"."currency" = "ge"."buyer_currency") GROUP BY ALL) UNION ALL (SELECT "platform", "date_granularity", "transaction_date", "transaction_type", "buyer_country", "sku", "transaction_currency", "exchange_rate", "transaction_amount_usd", CASE WHEN "transaction_type" = 'CHARGE' THEN "transaction_amount_local_currency" WHEN "transaction_type" = 'TAXES_AND_FEES' THEN "Taxes_and_Fees_local_currency" END AS "transaction_amount_local_currency", "transaction_amount_usd" * "ils_exchange_rate" AS "transaction_amount_ils" FROM (SELECT DISTINCT * FROM (SELECT 'ios' AS "platform", "date_granularity", "date" AS "transaction_date", "buyer_country", "sku", "transaction_currency", "exchange_rate", "ils"."exchange_rate" AS "ils_exchange_rate", SUM("transaction_amount_usd") AS "Charge", SUM("developer_proceeds_usd") AS "Taxes_and_Fees", SUM("transaction_amount_local_currency") AS "transaction_amount_local_currency", SUM("developer_proceeds") AS "Taxes_and_Fees_local_currency" FROM (SELECT date("ge1"."begin_date") AS "date", "ge1"."date_granularity" AS "date_granularity", "ge1"."title" AS "sku", "ge1"."country_code" AS "buyer_country", "ge1"."currency_of_proceeds" AS "transaction_currency", "er1"."rate" AS "exchange_rate", "ge1"."units" AS "units", ("ge1"."customer_price-ge1"."developer_proceeds") * "ge1"."units" * (-1) AS "developer_proceeds", "ge1"."customer_price" * "ge1"."units" AS "transaction_amount_local_currency", "ge1"."customer_price" * "ge1"."units" / "er1"."rate" AS "transaction_amount_usd", ("ge1"."customer_price-ge1"."developer_proceeds") * "ge1"."units" / "er1"."rate" * (-1) AS "developer_proceeds_usd" FROM (SELECT DISTINCT * FROM "staging"."raw"."apps_store_connect_sales") AS "ge1" INNER JOIN (SELECT DISTINCT * FROM "F_EXCHANGE_RATES") AS "er1" ON date("er1"."time") = date("ge1"."begin_date") AND "er1"."currency" = "ge1"."currency_of_proceeds") LEFT JOIN (SELECT date("time") AS "date", "currency", "rate" AS "exchange_rate" FROM (SELECT DISTINCT * FROM "F_EXCHANGE_RATES") WHERE "currency" = 'ILS') AS "ils" USING ("date") GROUP BY ALL) UNPIVOT("transaction_amount_usd" FOR "transaction_type" IN ("Charge", "Taxes_and_Fees")))))`,
377377
]
378-
}
378+
},
379+
{
380+
title: '* with exclude single column',
381+
sql: [
382+
'SELECT table_a.* EXCLUDE column_in_table_a from tableName',
383+
'SELECT "table_a".* EXCLUDE "column_in_table_a" FROM "tableName"'
384+
]
385+
},
386+
{
387+
title: '* with exclude multiple columns',
388+
sql: [
389+
'select * exclude (user_id,daily_iap,iap_7d,iap_30d,purchases_cnt), count(distinct user_id)DAU from tableName',
390+
'SELECT * EXCLUDE("user_id", "daily_iap", "iap_7d", "iap_30d", "purchases_cnt"), COUNT(DISTINCT "user_id") AS "DAU" FROM "tableName"'
391+
]
392+
},
379393
]
380394
SQL_LIST.forEach(sqlInfo => {
381395
const { title, sql } = sqlInfo

0 commit comments

Comments
 (0)