Conversation
Signed-off-by: Alexis Rico <sferadev@gmail.com>
|
|
Your pull request has been published to npm. You can install @xata.io/client by running: Other packages are published like this: To test the CLI, run: |
size-limit report 📦
|
Signed-off-by: Alexis Rico <sferadev@gmail.com>
Signed-off-by: Alexis Rico <sferadev@gmail.com>
Signed-off-by: Alexis Rico <sferadev@gmail.com>
| name: text('name').notNull() | ||
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${usersDistinctTable}`); |
There was a problem hiding this comment.
We do not support DDL statements like DROP TABLE as the error message suggests:
'invalid SQL: unsupported statement type, available: [SELECT, INSERT, UPDATE, DELETE]'
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${usersDistinctTable}`); | ||
| await db.execute(sql`create table ${usersDistinctTable} (id integer, name text)`); |
There was a problem hiding this comment.
We do not support DDL statements like CREATE TABLE as the error message suggests:
'invalid SQL: unsupported statement type, available: [SELECT, INSERT, UPDATE, DELETE]'
| name: usersTable.name | ||
| }); | ||
|
|
||
| t.deepEqual(users, [{ id: 1, name: 'Jane' }]); |
There was a problem hiding this comment.
The id is not 1 but rather the Xata generated id that has a format rec_{randomstring}. Also, id is a read only field, we do not support users setting it.
| await db.insert(usersTable).values({ name: 'John' }); | ||
| const users = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')).returning(); | ||
|
|
||
| t.assert(users[0]!.createdAt instanceof Date); |
There was a problem hiding this comment.
Xata contains the right timestamp. However, the timestamp format differs from the one we have for xata internal fields. For example, created_at is 2023-10-06T09:53:49.276Z but our internal xata.creadtedAt field contains 2023-10-06T09:53:49.276755Z (note the precision difference). Mayb that's why datetime parsing fails and we get invalid date errors?
| t.deepEqual(result, [{ id: 1, name: 'Atlanta', state: 'GA' }]); | ||
| }); | ||
|
|
||
| test.skip('char delete', async (t) => { |
| await db.insert(usersTable).values({ name: 'John', verified: true }); | ||
| const result = await db.select().from(usersTable); | ||
|
|
||
| t.deepEqual(result, [{ id: 1, name: 'John', verified: true, jsonb: null, createdAt: result[0]!.createdAt }]); |
There was a problem hiding this comment.
The id is incorrect and createdAt cannot be parsed.
| }) | ||
| .from(usersTable); | ||
|
|
||
| t.deepEqual(result, [ |
| verified: usersTable.verified | ||
| }); | ||
|
|
||
| t.deepEqual(result, [ |
| ]); | ||
| }); | ||
|
|
||
| test.skip('select with group by as field', async (t) => { |
There was a problem hiding this comment.
This test passes for me locally. Also, I do not see anything problematic.
| t.deepEqual(result, [{ name: 'Jane' }, { name: 'John' }]); | ||
| }); | ||
|
|
||
| test.skip('select with group by as sql', async (t) => { |
There was a problem hiding this comment.
This test passes for me locally. Also, I do not see anything problematic.
| .from(usersTable) | ||
| .groupBy(sql`${usersTable.name}`, usersTable.id); | ||
|
|
||
| t.deepEqual(result, [{ name: 'Jane' }, { name: 'Jane' }, { name: 'John' }]); |
There was a problem hiding this comment.
As the id is not numeric, the ordering can be different. Locally I get John, Jane, Jane. We get the right elements, but in a different order.
| .from(usersTable) | ||
| .groupBy(usersTable.id, sql`${usersTable.name}`); | ||
|
|
||
| t.deepEqual(result, [{ name: 'Jane' }, { name: 'Jane' }, { name: 'John' }]); |
There was a problem hiding this comment.
Ordering is different just like in the test above.
| t.deepEqual(result, [{ name: 'Jane' }, { name: 'Jane' }, { name: 'John' }]); | ||
| }); | ||
|
|
||
| test.skip('select with group by complex query', async (t) => { |
There was a problem hiding this comment.
It passes for me locally, and also it is supposed to work.
|
|
||
| await db.insert(usersTable).values({ name: sql`${'John'}` }); | ||
| const result = await db.select({ id: usersTable.id, name: usersTable.name }).from(usersTable); | ||
| t.deepEqual(result, [{ id: 1, name: 'John' }]); |
| .leftJoin(customerAlias, eq(customerAlias.id, 11)) | ||
| .where(eq(usersTable.id, 10)); | ||
|
|
||
| t.deepEqual(result, [ |
There was a problem hiding this comment.
As the IDs are incorrect in the select, the result is empty.
| name: text('name').notNull() | ||
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${users}`); |
There was a problem hiding this comment.
DROP and CREATE table clauses are not allowed.
| await db.insert(usersTable).values({ name: sql`'Jo h n'` }); | ||
| const result = await db.select({ id: usersTable.id, name: usersTable.name }).from(usersTable); | ||
|
|
||
| t.deepEqual(result, [{ id: 1, name: 'Jo h n' }]); |
| .prepare('statement1'); | ||
| const result = await statement.execute(); | ||
|
|
||
| t.deepEqual(result, [{ id: 1, name: 'John' }]); |
| }) | ||
| .from(usersTable); | ||
|
|
||
| t.deepEqual(result, [ |
| }) | ||
| .from(usersTable) | ||
| .where(eq(usersTable.id, placeholder('id'))) | ||
| .prepare('stmt3'); |
There was a problem hiding this comment.
AFAIK we do not support named prepared statements.
| }); | ||
|
|
||
| // TODO change tests to new structure | ||
| test.skip('migrator', async (t) => { |
There was a problem hiding this comment.
DDL statements are not supported.
| test.skip('insert via db.execute + select via db.execute', async (t) => { | ||
| const { db } = t.context; | ||
|
|
||
| await db.execute(sql`insert into ${usersTable} (${name(usersTable.name.name)}) values (${'John'})`); |
There was a problem hiding this comment.
insert into users("name") values('John'); supposed to work. That is the statement that is executed, correct?
| t.deepEqual(inserted.rows, [{ id: 1, name: 'John' }]); | ||
| }); | ||
|
|
||
| test.skip('build query insert with onConflict do update', async (t) => { |
There was a problem hiding this comment.
This seems to be an issue with the query builder, not the SQL proxy.
| }); | ||
| }); | ||
|
|
||
| test.skip('insert with onConflict do update', async (t) => { |
There was a problem hiding this comment.
There is no conflict because id is not 1, so the record is not updated.
| .from(usersTable) | ||
| .where(eq(usersTable.id, 1)); | ||
|
|
||
| t.deepEqual(res, [{ id: 1, name: 'John' }]); |
There was a problem hiding this comment.
For some reason id is a string here. It's curious that we allow setting the id...
| t.deepEqual(res, [{ id: 1, name: 'John' }]); | ||
| }); | ||
|
|
||
| test.skip('left join (flat object fields)', async (t) => { |
There was a problem hiding this comment.
This seems like an issue in the SQL proxy. The query
select "users2"."id", "users2"."name", "cities"."id", "cities"."name" from "users2" left join "cities" on "users2"."city_id" = "cities"."id"only returns
{
"records":[
{
"id":"rec_ckfv2p5c8vb65ejtq8s0"
"name":"Paris"
},
{
"id":""
"name":""
}
]
}There was a problem hiding this comment.
oh, it's a known issue: https://github.com/xataio/xata/issues/2572
There was a problem hiding this comment.
known issue: https://github.com/xataio/xata/issues/2572
| ]); | ||
| }); | ||
|
|
||
| test.skip('left join (grouped fields)', async (t) => { |
| .insert(courseCategoriesTable) | ||
| .values([{ name: 'Category 1' }, { name: 'Category 2' }, { name: 'Category 3' }, { name: 'Category 4' }]); | ||
|
|
||
| await db.insert(coursesTable).values([ |
There was a problem hiding this comment.
We return a constraint violation because the category IDs are incorrect.
| .select({ | ||
| region: orders.region, | ||
| product: orders.product, | ||
| productUnits: sql<number>`sum(${orders.quantity})::int`, |
There was a problem hiding this comment.
It seems to me that aliasing is missing the query. We run sum("quantity")::int, sum("amount")::int, and productUnits and productSales is missing from the query.
So I guess it has to be adjusted in the adapter to make sure the sums are displayed with the correct name. Or we can alias the sum with the name in the query.
| ]); | ||
| }); | ||
|
|
||
| test.skip('select from subquery sql', async (t) => { |
|
|
||
| const res = await db.select({ count: sql`count(*)` }).from(usersTable); | ||
|
|
||
| t.deepEqual(res, [{ count: '2' }]); |
There was a problem hiding this comment.
We return an integer, not a string.
| t.deepEqual(res, [{ count: '2' }]); | ||
| }); | ||
|
|
||
| test.skip('select count w/ custom mapper', async (t) => { |
| t.deepEqual(res, [{ count: 2 }]); | ||
| }); | ||
|
|
||
| test.skip('network types', async (t) => { |
|
|
||
| await db.insert(salEmp).values(values); | ||
|
|
||
| const res = await db.select().from(salEmp); |
There was a problem hiding this comment.
The backend returns the correct reponse:
{
"records": [
{
"name": "John",
"pay_by_quarter": [
"10000",
"10000",
"10000",
"10000"
],
"schedule": [
"meeting",
"lunch",
"training",
"presentation"
]
},
{
"name": "Carol",
"pay_by_quarter": [
"20000",
"25000",
"25000",
"25000"
],
"schedule": [
"breakfast",
"consulting",
"meeting",
"lunch"
]
}
]
}But I get the following JS error:
TypeError {
message: 'Cannot read properties of undefined (reading \'map\')',
}
| await db.insert(citiesTable).values([{ name: 'London' }, { name: 'Paris' }, { name: 'New York' }]); | ||
|
|
||
| await db.insert(users2Table).values([ | ||
| { name: 'John', cityId: 1 }, |
There was a problem hiding this comment.
Id is incorrect so we return a constraint violation error.
| cityId: integer('city_id').notNull() | ||
| }).existing(); | ||
|
|
||
| await db.execute(sql`create view ${newYorkers1} as ${getViewConfig(newYorkers1).query}`); |
There was a problem hiding this comment.
We do not allow creating views.
| cityId: integer('city_id').notNull() | ||
| }).existing(); | ||
|
|
||
| await db.execute(sql`create materialized view ${newYorkers1} as ${getMaterializedViewConfig(newYorkers1).query}`); |
There was a problem hiding this comment.
We do not allow creating materialized views.
|
|
||
| Expect<Equal<{ userId: number; name: string; userCity: string; cityId: number; cityName: string }[], typeof result>>; | ||
|
|
||
| t.deepEqual(result, [{ userId: 1, name: 'John', userCity: 'New York', cityId: 1, cityName: 'Paris' }]); |
There was a problem hiding this comment.
known issue: https://github.com/xataio/xata/issues/2572
|
|
||
| Expect<Equal<{ userId: number; name: string; userCity: string; cityId: number; cityName: string }[], typeof result>>; | ||
|
|
||
| t.deepEqual(result, [{ userId: 1, name: 'John', userCity: 'New York', cityId: 1, cityName: 'Paris' }]); |
There was a problem hiding this comment.
Both incorrect ID and the known issue we have: https://github.com/xataio/xata/issues/2572
| name: text('name').notNull() | ||
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${users}`); |
There was a problem hiding this comment.
No DROP TABLE support in Xata.
| await db.execute(sql`drop table if exists ${users}`); | ||
|
|
||
| await db.execute( | ||
| sql`create table myprefix_test_prefixed_table_with_unique_name (id integer not null primary key, name text not null)` |
There was a problem hiding this comment.
No CREATE TABLE support in Xata.
| .default(sql`now()`) | ||
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${exercises}`); |
| createdAt: timestamp('created_at').notNull() | ||
| }); | ||
|
|
||
| await db.execute(sql`drop table if exists ${metricEntry}`); |
There was a problem hiding this comment.
No DROP TABLE and CREATE TABLE support in Xata.
|
|
||
| await db.execute( | ||
| sql` | ||
| create table users_test_with_and_without_timezone ( |
| .returning() | ||
| .then((rows) => rows[0]!); | ||
|
|
||
| await db.transaction(async (tx) => { |
There was a problem hiding this comment.
We do not support transactions.
| await db.execute(sql`drop table ${products}`); | ||
| }); | ||
|
|
||
| test.skip('transaction rollback', async (t) => { |
There was a problem hiding this comment.
We do not support transaction rollback.
There was a problem hiding this comment.
I went through all of the tests in the pull request. There is one issue that has to be fixed in the proxy: https://github.com/xataio/xata/issues/2572
Other reasons of test failures:
- Timestamp format differs from what we support, so the test fails to parse the timestamp from PostgreSQL
- When running functions PostgreSQL uses the function name as the column name, but the tests expect it to be the column name
- DDL statements and transactions are not supported
- The tests all try to set the ID for the records, but we return our own IDs. When the tests tries to use the bad ID, we return nothing, as the ID is unknown to us.
- We use our IDs in linked tables, so the tests' IDs do not work
So on the SQL proxy side we have to fix the known issue, and maybe rethink how we handle the IDs. Should we get rid of our ID format?
Also, we will support more DDL commands in the future.
How to run them locally
.envfile withXATA_API_KEYandXATA_WORKSPACE. If you want to connect somewhere different than production useXATA_API_PROVIDERand/orXATA_REGION.pnpm installpackages/plugin-client-drizzlerunpnpm test.skipfromtest.skip(...)