Skip to content

Commit

Permalink
fix(funcSubquery): nesting variable
Browse files Browse the repository at this point in the history
  • Loading branch information
Hieuzest committed Nov 2, 2023
1 parent f11557b commit 08102d6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
1 change: 0 additions & 1 deletion packages/mongo/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export class Transformer {
} else if (this.refTables.includes(expr.$[0])) {
return `$$${expr.$[0]}.` + this.getActualKey(expr.$[1], expr.$[0])
} else {
console.log(this.tables, this.refTables)
throw new Error(`$ not transformed: ${JSON.stringify(expr)}`)

Check warning on line 115 in packages/mongo/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mongo/src/utils.ts#L115

Added line #L115 was not covered by tests
}
}
Expand Down
14 changes: 8 additions & 6 deletions packages/mysql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ class MySQLBuilder extends Builder {
const { args: [expr], ref, table, tables } = sel
const thisTables = this.tables, thisState = this.state
this.tables = { ...tables }
this.state = { group: true, wrappedSubquery: true, refTables: { ...(this.state.refTables || {}), ...(thisTables || {}) } }
const output = this.parseEval(expr)
this.state = { wrappedSubquery: true, refTables: { ...(this.state.refTables || {}), ...(thisTables || {}) } }
const inner = this.get(table as Selection, true) as string
this.state.group = true
const output = this.parseEval(expr, false)
const refFields = this.state.refFields
this.tables = thisTables
thisState.sqlType = this.state.sqlType
this.state = thisState
let query: string
if (!(sel.args[0] as any).$) {
Expand All @@ -193,12 +195,12 @@ class MySQLBuilder extends Builder {
}
if (Object.keys(refFields ?? {}).length) {
const funcname = `minato_tfunc_${randomId()}`
const keys = Object.keys(refFields ?? {}).map(x => `${x} JSON`).join(',')
const decls = Object.values(refFields ?? {}).map(x => `${x} JSON`).join(',')
const args = Object.keys(refFields ?? {}).map(x => this.state.refFields?.[x] ?? x).map(x => this.jsonQuote(x, true)).join(',')
this.prequeries.push(`DROP FUNCTION IF EXISTS ${funcname}`)
this.prequeries.push(`CREATE FUNCTION ${funcname} (${keys}) RETURNS JSON DETERMINISTIC RETURN ${this.jsonQuote(query)}`)
query = `${funcname}(${Object.values(refFields ?? {}).map(x => this.jsonQuote(x, true)).join(',')})`
this.prequeries.push(`CREATE FUNCTION ${funcname} (${decls}) RETURNS JSON DETERMINISTIC RETURN ${this.jsonQuote(query)}`)
this.state.sqlType = 'json'
return query
return `${funcname}(${args})`
} else return query
}

Expand Down
12 changes: 7 additions & 5 deletions packages/sql-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,13 @@ export class Builder {
const { args: [expr], ref, table, tables } = sel
const thisTables = this.tables, thisState = this.state
this.tables = { ...tables }
this.state = { group: true, refTables: { ...(this.state.refTables || {}), ...(thisTables || {}) } }
const output = this.parseEval(expr)
this.state = { refTables: { ...(this.state.refTables || {}), ...(thisTables || {}) } }
const inner = this.get(table as Selection, true) as string
this.state.group = true
const output = this.parseEval(expr, false)
this.tables = thisTables
thisState.sqlType = this.state.sqlType
this.state = thisState
console.log(inner)
if (!(sel.args[0] as any).$) {
this.state.sqlType = 'raw'
if (inner.startsWith('(') && inner.endsWith(')')) {
Expand Down Expand Up @@ -380,10 +381,11 @@ export class Builder {
const res = (fields[key]?.expr) ? this.parseEvalExpr(fields[key]?.expr)
: this.transformKey(key, fields, `${escapeId(table)}.`, `${table}.${key}`)
if (this.state.wrappedSubquery) {
if (res in (this.state.refFields ?? {})) return this.state.refFields![res]
const key = `minato_tvar_${randomId()}`
;(this.state.refFields ??= {})[key] = res
;(this.state.refFields ??= {})[res] = key
this.state.sqlType = 'json'
return this.jsonUnquote(escapeId(key))
return escapeId(key)
} else return res
}

Expand Down
20 changes: 20 additions & 0 deletions packages/tests/src/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,26 @@ namespace SelectionTests {
{ x: [4] },
])
})

it('return nested array', async () => {
await expect(database.select('foo')
.project({
x: r => database.select('bar')
.where(row => $.and($.gte(row.pid, r.id), $.lt(row.uid, r.id)))
.project({
id: _ => database.select('foo').project({
id: row => $.add(row.id, r.id),
}).evaluate('id')
})
.evaluate('id')
})
.execute())
.to.eventually.deep.equal([
{ x: [] },
{ x: [[3, 4, 5], [3, 4, 5]] },
{ x: [[4, 5, 6]] },
])
})
}
}

Expand Down

0 comments on commit 08102d6

Please sign in to comment.