Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ By generating an explicit `SELECT` statement that recursively expands `RECORD` a

- `jq` installed on your system.
- `bash` shell.
- `bq` (Google Cloud SDK) for direct table schema fetching.

### Usage

Expand Down Expand Up @@ -125,43 +126,43 @@ Input `my_schema.json`:
Generates:
```sql
SELECT
`A`,
`B`,
A,
B,
STRUCT(
STRUCT(
`C`.`D`.`E`,
C.D.E,
ARRAY(
SELECT AS STRUCT
`F`.`G`
F.G
FROM
UNNEST(`C`.`D`.`F`) AS `F`
UNNEST(C.D.F) AS F
WITH
OFFSET
ORDER BY
OFFSET
) AS `F`
) AS `D`,
`C`.`H`
) AS `C`,
) AS F
) AS D,
C.H
) AS C,
STRUCT(
`I`.`J`,
`I`.`K`
) AS `I`,
I.J,
I.K
) AS I,
ARRAY(
SELECT AS STRUCT
`L`.`M`,
`L`.`N`,
L.M,
L.N,
STRUCT(
`L`.`O`.`P`
) AS `O`
L.O.P
) AS O
FROM
UNNEST(`L`) AS `L`
UNNEST(L) AS L
WITH
OFFSET
ORDER BY
OFFSET
) AS `L`,
`Q`
) AS L,
Q
```

In case you would like to use snake_case for field names use flag `--use_snake_case`:
Expand Down
12 changes: 8 additions & 4 deletions bin/bigquery-schema-select
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ if [[ "$1" == "--use_snake_case" ]]; then
fi

echo "$INPUT" | jq -r --argjson useSnakeCase "$USE_SNAKE_CASE" '
def quoteName(name): "`" + name + "`";
def isReserved(name):
name | ascii_downcase | test("^(all|and|any|array|as|asc|assert_rows_modified|at|between|by|case|cast|check|collate|column|contains|create|cross|cube|current|date|default|define|desc|distinct|else|end|enum|escape|except|exclude|exists|extract|false|fetch|following|for|from|full|group|grouping|groups|having|if|ignore|in|inner|intersect|interval|into|is|join|lateral|left|like|limit|lookup|merge|natural|new|no|not|null|nulls|of|on|or|order|outer|over|partition|preceding|proto|range|recursive|respect|right|rollup|rows|select|set|some|struct|tablesample|then|to|treat|true|unbounded|union|unnest|using|when|where|window|with|within)$");

def quoteIfNeeded(name):
if (isReserved(name) or (name | test("[^a-zA-Z0-9_]"))) then "`" + name + "`" else name end;

def calculateFieldName(name; useSnakeCase):
if (useSnakeCase | not) then name
Expand All @@ -48,16 +52,16 @@ echo "$INPUT" | jq -r --argjson useSnakeCase "$USE_SNAKE_CASE" '
end;

def toSelectClauseRecursive(current; depth; prefix; useSnakeCase):
(if (prefix == null) then quoteName(current.name) else prefix + "." + quoteName(current.name) end) as $fullyQualifiedName |
(if (prefix == null) then quoteIfNeeded(current.name) else prefix + "." + quoteIfNeeded(current.name) end) as $fullyQualifiedName |
(" " * depth) as $indent |
calculateFieldName(current.name; useSnakeCase) as $calculatedFieldName |
quoteName($calculatedFieldName) as $quotedCalculatedFieldName |
quoteIfNeeded($calculatedFieldName) as $quotedCalculatedFieldName |
(if (useSnakeCase and $calculatedFieldName != current.name) then " AS " + $quotedCalculatedFieldName else "" end) as $alias |

if (current.type != "RECORD") then
$indent + $fullyQualifiedName + $alias
elif (current.type == "RECORD" and current.mode == "REPEATED") then
quoteName(current.name) as $currentNameQuoted |
quoteIfNeeded(current.name) as $currentNameQuoted |
($indent + "ARRAY(\n" +
$indent + " SELECT AS STRUCT\n" +
(current.fields | map(toSelectClauseRecursive(.; depth + 2; $currentNameQuoted; useSnakeCase)) | join(",\n")) + "\n" +
Expand Down
38 changes: 19 additions & 19 deletions test-resources/my_camel_select.sql
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
SELECT
`AField1` AS `a_field1`,
`BField2` AS `b_field2`,
AField1 AS a_field1,
BField2 AS b_field2,
STRUCT(
STRUCT(
`CField3`.`DField4`.`EField5` AS `e_field5`,
CField3.DField4.EField5 AS e_field5,
ARRAY(
SELECT AS STRUCT
`FField6`.`GField7` AS `g_field7`
FField6.GField7 AS g_field7
FROM
UNNEST(`CField3`.`DField4`.`FField6`) AS `FField6`
UNNEST(CField3.DField4.FField6) AS FField6
WITH
OFFSET
ORDER BY
OFFSET
) AS `f_field6`
) AS `d_field4`,
`CField3`.`HField8` AS `h_field8`
) AS `c_field3`,
) AS f_field6
) AS d_field4,
CField3.HField8 AS h_field8
) AS c_field3,
STRUCT(
`IField9`.`JField10` AS `j_field10`,
`IField9`.`KField11` AS `k_field11`
) AS `i_field9`,
IField9.JField10 AS j_field10,
IField9.KField11 AS k_field11
) AS i_field9,
ARRAY(
SELECT AS STRUCT
`LField12`.`MField13` AS `m_field13`,
`LField12`.`NField14` AS `n_field14`,
LField12.MField13 AS m_field13,
LField12.NField14 AS n_field14,
STRUCT(
`LField12`.`OField15`.`PField16` AS `p_field16`
) AS `o_field15`
LField12.OField15.PField16 AS p_field16
) AS o_field15
FROM
UNNEST(`LField12`) AS `LField12`
UNNEST(LField12) AS LField12
WITH
OFFSET
ORDER BY
OFFSET
) AS `l_field12`,
`QField17` AS `q_field17`
) AS l_field12,
QField17 AS q_field17
28 changes: 14 additions & 14 deletions test-resources/my_camel_short_select.sql
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
SELECT
`myPrimitive` AS `my_primitive`,
myPrimitive AS my_primitive,
STRUCT(
`myStruct`.`myA` AS `my_a`,
`myStruct`.`myB` AS `my_b`
) AS `my_struct`,
myStruct.myA AS my_a,
myStruct.myB AS my_b
) AS my_struct,
STRUCT(
`myStructOfStruct`.`my1`,
myStructOfStruct.my1,
STRUCT(
`myStructOfStruct`.`my2Struct`.`my2`
) AS `my2_struct`
) AS `my_struct_of_struct`,
`myRepeatedPrimitive` AS `my_repeated_primitive`,
myStructOfStruct.my2Struct.my2
) AS my2_struct
) AS my_struct_of_struct,
myRepeatedPrimitive AS my_repeated_primitive,
ARRAY(
SELECT AS STRUCT
`myRepeatedStruct`.`myX` AS `my_x`,
`myRepeatedStruct`.`myY` AS `my_y`
myRepeatedStruct.myX AS my_x,
myRepeatedStruct.myY AS my_y
FROM
UNNEST(`myRepeatedStruct`) AS `myRepeatedStruct`
UNNEST(myRepeatedStruct) AS myRepeatedStruct
WITH
OFFSET
ORDER BY
OFFSET
) AS `my_repeated_struct`,
`nochange`
) AS my_repeated_struct,
nochange
38 changes: 19 additions & 19 deletions test-resources/my_select.sql
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
SELECT
`A`,
`B`,
A,
B,
STRUCT(
STRUCT(
`C`.`D`.`E`,
C.D.E,
ARRAY(
SELECT AS STRUCT
`F`.`G`
F.G
FROM
UNNEST(`C`.`D`.`F`) AS `F`
UNNEST(C.D.F) AS F
WITH
OFFSET
ORDER BY
OFFSET
) AS `F`
) AS `D`,
`C`.`H`
) AS `C`,
) AS F
) AS D,
C.H
) AS C,
STRUCT(
`I`.`J`,
`I`.`K`
) AS `I`,
I.J,
I.K
) AS I,
ARRAY(
SELECT AS STRUCT
`L`.`M`,
`L`.`N`,
L.M,
L.N,
STRUCT(
`L`.`O`.`P`
) AS `O`
L.O.P
) AS O
FROM
UNNEST(`L`) AS `L`
UNNEST(L) AS L
WITH
OFFSET
ORDER BY
OFFSET
) AS `L`,
`Q`
) AS L,
Q
Loading