-
Notifications
You must be signed in to change notification settings - Fork 703
Another round of fixes for null columns handling #3103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -875,4 +875,23 @@ inline Datum pointer_to_datum(const void* curr_val, Oid attr_typeid, int32_t att | |||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| template <typename T> | ||||||||||
| nd::array eval_with_nones(nd::array arr) | ||||||||||
| { | ||||||||||
| try { | ||||||||||
| return nd::eval(arr); | ||||||||||
| } catch (const nd::invalid_dynamic_eval&) { | ||||||||||
|
||||||||||
| } catch (const nd::invalid_dynamic_eval&) { | |
| } catch (const nd::invalid_dynamic_eval&) { | |
| // nd::eval failed due to an invalid dynamic evaluation (e.g. incompatible shapes). | |
| // This is expected for some inputs; fall back to element-wise evaluation with None handling below. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,278 @@ | ||||||
| """ | ||||||
| Test adding multiple NUMERIC columns to a deeplake table and updating them. | ||||||
| This test verifies that: | ||||||
| - Creating a table with SERIAL PRIMARY KEY and TEXT columns works | ||||||
| - Adding NUMERIC columns dynamically works correctly | ||||||
| - Inserting rows with NULL numeric values works (stored as 0 in deeplake) | ||||||
| - Querying after multiple schema changes works | ||||||
| - Multiple NUMERIC columns can be added sequentially | ||||||
| - UPDATE operations work correctly on numeric columns | ||||||
| - Multi-column updates work correctly | ||||||
| """ | ||||||
| import pytest | ||||||
| import asyncpg | ||||||
| from test_utils.assertions import Assertions | ||||||
|
|
||||||
|
|
||||||
| @pytest.mark.asyncio | ||||||
| async def test_add_multiple_numeric_columns_with_null(db_conn: asyncpg.Connection): | ||||||
| """ | ||||||
| Test adding multiple NUMERIC columns, inserting, and updating values. | ||||||
| Tests: | ||||||
| - Create table with SERIAL PRIMARY KEY and TEXT column using deeplake | ||||||
| - Query with ORDER BY and LIMIT/OFFSET | ||||||
| - Add first NUMERIC column via ALTER TABLE | ||||||
| - Verify column is added and query works | ||||||
| - Insert row with empty string and NULL NUMERIC value | ||||||
| - Add second NUMERIC column via ALTER TABLE | ||||||
| - Verify all columns are present and NULL numeric values are stored as 0 | ||||||
| - UPDATE single row with specific numeric values | ||||||
| - UPDATE multiple rows in batch | ||||||
| - UPDATE single column while leaving others unchanged | ||||||
| - UPDATE multiple columns including TEXT and NUMERIC together | ||||||
| - Verify final state of all rows after updates | ||||||
| """ | ||||||
| assertions = Assertions(db_conn) | ||||||
|
|
||||||
| try: | ||||||
| # Create table with id (SERIAL) and name (TEXT) columns using deeplake | ||||||
| await db_conn.execute(""" | ||||||
| CREATE TABLE users ( | ||||||
| id SERIAL PRIMARY KEY, | ||||||
| name TEXT NOT NULL | ||||||
| ) USING deeplake | ||||||
| """) | ||||||
|
|
||||||
| # Query on users table (should be empty initially) | ||||||
| rows = await db_conn.fetch(""" | ||||||
| SELECT * FROM (SELECT * FROM users ORDER BY "id") sub | ||||||
| LIMIT 20 OFFSET 0 | ||||||
| """) | ||||||
| assert len(rows) == 0, f"Expected 0 rows initially, got {len(rows)}" | ||||||
|
|
||||||
| # Add first numeric column to users | ||||||
| await db_conn.execute(""" | ||||||
| ALTER TABLE users ADD COLUMN "uu" NUMERIC | ||||||
| """) | ||||||
|
|
||||||
| # Verify column was added to PostgreSQL catalog | ||||||
| column_info = await db_conn.fetch(""" | ||||||
| SELECT column_name, data_type | ||||||
| FROM information_schema.columns | ||||||
| WHERE table_name = 'users' | ||||||
| ORDER BY ordinal_position | ||||||
| """) | ||||||
| column_names = [col['column_name'] for col in column_info] | ||||||
| assert 'uu' in column_names, \ | ||||||
| f"Column 'uu' should exist in catalog. Found: {column_names}" | ||||||
|
|
||||||
| # Query users table after first schema change (still empty) | ||||||
| rows = await db_conn.fetch(""" | ||||||
| SELECT * FROM (SELECT * FROM users ORDER BY "id") sub | ||||||
| LIMIT 20 OFFSET 0 | ||||||
| """) | ||||||
| assert len(rows) == 0, f"Expected 0 rows after adding column, got {len(rows)}" | ||||||
|
|
||||||
| # Insert row with empty name and NULL UUID (numeric column) | ||||||
|
||||||
| # Insert row with empty name and NULL UUID (numeric column) | |
| # Insert row with empty name and NULL numeric value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function lacks documentation explaining its purpose, parameters, return value, and when it should be used instead of plain nd::eval. Add a docstring explaining that this function evaluates arrays containing NULL values by replacing them with default-constructed values of type T.