Skip to content

Commit

Permalink
rename (updated 12:36)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkal committed Sep 5, 2024
1 parent 5f987f6 commit 6fc27e2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 24 deletions.
18 changes: 11 additions & 7 deletions packages/typegen/src/query/analyze-select-statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {createHash} from 'crypto'
import * as lodash from 'lodash'
import {parse, toSql} from 'pgsql-ast-parser'
import {z} from 'zod'
import {aliasMappings, getASTModifiedToSingleSelect, ModifiedAST} from './parse'
import {getAliasInfo, getASTModifiedToSingleSelect, ModifiedAST} from './parse'

/**
* Returns a list of results that stem from a special query used to retrieve type information from the database.
Expand Down Expand Up @@ -44,19 +44,19 @@ export const analyzeSelectStatement = async (
const modifiedAst = getASTModifiedToSingleSelect(toSql.statement(statement))
const analyzed = await analyzeSelectStatement(tx, modifiedAst)

const statementAliasInfo = aliasMappings(statement)
const aliasInfoList = getAliasInfo(statement)
const aliasList = analyzed[0].column_aliases

const tempTableColumns = aliasList.map(aliasName => {
const found = statementAliasInfo.find(info => info.queryColumn === aliasName)
if (!found) throw new Error(`Alias ${aliasName} not found in statement`)
const aliasInfo = aliasInfoList.find(info => info.queryColumn === aliasName)
if (!aliasInfo) throw new Error(`Alias ${aliasName} not found in statement`)

const analyzedResult = analyzed.find(a => a.table_column_name === found.aliasFor)
const analyzedResult = analyzed.find(a => a.table_column_name === aliasInfo.aliasFor)
if (!analyzedResult) throw new Error(`Alias ${aliasName} not found in analyzed results`)

const def = `${aliasName} ${analyzedResult.underlying_data_type} ${analyzedResult.is_underlying_nullable === 'NO' ? 'not null' : ''}`

const comment = `From CTE expression "${tableAlias.name}", column source: ${analyzedResult.schema_name}.${analyzedResult.underlying_table_name}.${analyzedResult.table_column_name}`
const comment = `From CTE subquery "${tableAlias.name}", column source: ${analyzedResult.schema_name}.${analyzedResult.underlying_table_name}.${analyzedResult.table_column_name}`
return {
name: aliasName,
def,
Expand All @@ -70,7 +70,11 @@ export const analyzeSelectStatement = async (
${tempTableColumns.map(c => c.def).join(',\n')}
);
${tempTableColumns.map(c => `comment on column ${schemaName}.${tableAlias.name}.${c.name} is '${c.comment}';`).join('\n')}
${tempTableColumns
.map(c => {
return `comment on column ${schemaName}.${tableAlias.name}.${c.name} is '${c.comment}';`
})
.join('\n')}
`)
await tx.query(raw)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/typegen/src/query/column-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {tryOrDefault} from '../util'
import {memoizeQueryFn} from '../utils/memoize'
import {SelectStatementAnalyzedColumn, analyzeSelectStatement} from './analyze-select-statement'
import {
aliasMappings,
getAliasInfo,
getASTModifiedToSingleSelect,
getSuggestedTags,
isParseable,
Expand Down Expand Up @@ -58,7 +58,7 @@ const getFieldInfo = (
// console.warn('using originalAst', {formattedQuery, originalSql})
}

const mappings = aliasMappings(ast)
const mappings = getAliasInfo(ast)

const relatedResults = mappings.flatMap(c =>
selectStatementColumns
Expand Down
27 changes: 23 additions & 4 deletions packages/typegen/src/query/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,29 @@ const expressionName = (ex: pgsqlAST.Expr): string | undefined => {
return undefined
}

export interface AliasMapping {
export interface AliasInfo {
/**
* The column name in the query,
* - e.g. in `select a as x from foo` this would be x
* - e.g. in `select a from foo` this would be a
*/
queryColumn: string
/**
* The column name in the query,
* - e.g. in `select a as x from foo` this would be a
*/
aliasFor: string
/**
* The table name(s) the column could be from,
* - e.g. in `select a from foo` this would be foo
* - e.g. in `select a from foo join bar on foo.id = bar.id` this would be foo and bar
*/
tablesColumnCouldBeFrom: string[]
/**
* Whether the column could be nullable via a join,
* - e.g. in `select a from foo` this would be false
* - e.g. in `select a from foo left join bar on foo.id = bar.id` this would be true
*/
hasNullableJoin: boolean
}
/**
Expand All @@ -217,7 +236,7 @@ export interface AliasMapping {
* list of `tablesColumnCouldBeFrom`. For simple queries like `select id from messages` it'll get sensible results, though, and those
* results can be used to look for non-nullability of columns.
*/
export const aliasMappings = (statement: pgsqlAST.Statement): AliasMapping[] => {
export const getAliasInfo = (statement: pgsqlAST.Statement): AliasInfo[] => {
assert.strictEqual(statement.type, 'select' as const)
assert.ok(statement.columns, `Can't get alias mappings from query with no columns`)

Expand Down Expand Up @@ -262,7 +281,7 @@ export const aliasMappings = (statement: pgsqlAST.Statement): AliasMapping[] =>
`Some aliases are duplicated, this is too confusing. ${JSON.stringify({aliasGroups})}`,
)

return statement.columns.reduce<AliasMapping[]>((mappings, {expr, alias}) => {
return statement.columns.reduce<AliasInfo[]>((mappings, {expr, alias}) => {
if (expr.type === 'ref') {
return mappings.concat({
queryColumn: alias?.name ?? expr.name,
Expand Down Expand Up @@ -294,7 +313,7 @@ export const suggestedTags = ({tables, columns}: ReturnType<typeof sqlTablesAndC

export const getSuggestedTags = lodash.flow(templateToValidSql, sqlTablesAndColumns, suggestedTags)

export const getAliasMappings = lodash.flow(getASTModifiedToSingleSelect, m => m.ast, aliasMappings)
export const getAliasMappings = lodash.flow(getASTModifiedToSingleSelect, m => m.ast, getAliasInfo)

export const removeSimpleComments = (sql: string) =>
sql
Expand Down
22 changes: 11 additions & 11 deletions packages/typegen/test/cte.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ test(`statement with CTE`, async () => {
/** - query: \`with abc as (select a as aaa from test_t... [truncated] ...b from abc join def on abc.aaa = def.bbb\` */
export interface Abc_Def {
/**
* From CTE expression "abc", column source: public.test_table1.a
* From CTE subquery "abc", column source: public.test_table1.a
*
* column: \`✨.abc.aaa\`, not null: \`true\`, regtype: \`integer\`
*/
aaa: number
/**
* From CTE expression "def", column source: public.test_table2.b
* From CTE subquery "def", column source: public.test_table2.b
*
* column: \`✨.def.bbb\`, regtype: \`double precision\`
*/
Expand Down Expand Up @@ -165,7 +165,7 @@ test(`statement with complex CTE`, async () => {
/** - query: \`with abc as (select table_name from info... [truncated] ...on_schema.tables, abc) select * from def\` */
export interface Def {
/**
* From CTE expression "def", column source: information_schema.tables.table_schema
* From CTE subquery "def", column source: information_schema.tables.table_schema
*
* column: \`✨.def.table_schema\`, regtype: \`name\`
*/
Expand Down Expand Up @@ -214,7 +214,7 @@ test(`statement with confusingly-named CTE`, async () => {
/** - query: \`with test_table1 as (select b as a from test_table2) select a from test_table1\` */
export interface TestTable1 {
/**
* From CTE expression "test_table1", column source: public.test_table2.b
* From CTE subquery "test_table1", column source: public.test_table2.b
*
* column: \`✨.test_table1.a\`, regtype: \`double precision\`
*/
Expand Down Expand Up @@ -287,49 +287,49 @@ test(`statement with CTE with crazy ordering`, async () => {
/** - query: \`with x as ( select b as b1, a as a1, a a... [truncated] ...ble1.a = test_table2.b ) select * from x\` */
export interface X {
/**
* From CTE expression "x", column source: public.test_table2.b
* From CTE subquery "x", column source: public.test_table2.b
*
* column: \`✨.x.b1\`, regtype: \`double precision\`
*/
b1: number | null
/**
* From CTE expression "x", column source: public.test_table1.a
* From CTE subquery "x", column source: public.test_table1.a
*
* column: \`✨.x.a1\`, not null: \`true\`, regtype: \`integer\`
*/
a1: number
/**
* From CTE expression "x", column source: public.test_table1.a
* From CTE subquery "x", column source: public.test_table1.a
*
* column: \`✨.x.a2\`, not null: \`true\`, regtype: \`integer\`
*/
a2: number
/**
* From CTE expression "x", column source: public.test_table1.a
* From CTE subquery "x", column source: public.test_table1.a
*
* column: \`✨.x.a3\`, not null: \`true\`, regtype: \`integer\`
*/
a3: number
/**
* From CTE expression "x", column source: public.test_table2.b
* From CTE subquery "x", column source: public.test_table2.b
*
* column: \`✨.x.b2\`, regtype: \`double precision\`
*/
b2: number | null
/**
* From CTE expression "x", column source: public.test_table1.a
* From CTE subquery "x", column source: public.test_table1.a
*
* column: \`✨.x.a4\`, not null: \`true\`, regtype: \`integer\`
*/
a4: number
/**
* From CTE expression "x", column source: public.test_table2.b
* From CTE subquery "x", column source: public.test_table2.b
*
* column: \`✨.x.b3\`, regtype: \`double precision\`
*/
Expand Down

0 comments on commit 6fc27e2

Please sign in to comment.