Failed to commit transaction: Error evaluating predicate: Generic DeltaTable error: Internal error: arrow_cast should have been simplified to cast.
- Dominant language
- Rust
- Stars
- 9.3k
- Forks
- 2.4k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 344
Description
### Describe the bug
I run into the error when I use my merger code a second time. The code to reproduce is attached. Versions below.
```
CommitFailedError: Failed to commit transaction: Error evaluating predicate: Generic DeltaTable error: Internal error: arrow_cast should have been simplified to cast.
This was likely caused by a bug in DataFusion's code and we would welcome that you file an bug report in our issue tracker
```
### To Reproduce
```
import pandas as pd
import pyarrow as pa
import numpy as np
from datetime import datetime, timedelta
import random
def generate_random_data(record_count):
# Generate random state strings
states = ['state1', 'state2', 'state3', 'state4', 'state5']
state_data = np.random.choice(states, record_count)
# Generate random timestamps between 2020/07/01 and now
start_date = datetime(2020, 7, 1)
end_date = datetime.now()
ts_data = [start_date + timedelta(days=random.randint(0, (end_date - start_date).days)) for _ in range(record_count)]
# Generate random counts
count_data = np.random.randint(1, 100, record_count)
# Generate random buckets between 0 and 30
bucket_data = np.random.randint(0, 31, record_count)
# Generate partition_year_month from ts_data
partition_year_month_data = [ts.strftime('%Y-%m') for ts in ts_data]
# Create a pandas DataFrame
df = pd.DataFrame({
'state': state_data,
'ts': ts_data,
'count': count_data,
'bucket': bucket_data,
'partition_year_month': partition_year_month_data
})
# Convert the DataFrame to a PyArrow Table
table = pa.Table.from_pandas(df)
return table
def merge(dt, results, merge_keys, columns=None, update=True, insert=True):
merge_stmts = []
for merge_key in merge_keys:
merge_stmts.append(f"target.{merge_key} = source.{merge_key}")
while True:
try:
# Process a single chunk here (just printing as an example)
batch = results.read_next_batch()
merger = dt.merge(
source=batch,
predicate=" and ".join(merge_stmts),
source_alias="source",
target_alias="target",
)
if update:
if columns is None:
merger = merger.when_matched_update_all()
else:
merger = merger.when_matched_update(columns)
if insert:
merger = merger.when_not_matched_insert_all()
log.info(merger.execute())
except StopIteration:
log.info("Finished all batches")
break
log.info("Compacting")
delta_table_optimizer = TableOptimizer(dt)
log.info(delta_table_optimizer.compact())
log.info("Vacuuming")
log.info(dt.vacuum(dry_run=False, retention_hours=0, enforce_retention_duration=False))
dt.cleanup_metadata()
try:
dt.create_checkpoint()
except Exception as e:
log.info(f"Checkpoint creation failed: {e}")
last_version = dt.version()
return last_version
```
```
dummy = {}
dtypes = {}
dummy['state'] = pd.Series("DUMMY", dtype="string[pyarrow]")
dtypes['state'] = pa.string()
dummy['ts'] = pd.Series(0, dtype="datetime64[ns]")
dtypes['ts'] = pa.timestamp("us", "UTC")
dummy['count'] = pd.Series(-1, dtype="int64[pyarrow]")
dtypes['count'] = pa.int64()
dummy['bucket'] = pd.Series(-1, dtype="int64[pyarrow]")
dtypes['bucket'] = pa.int64()
dummy['partition_year_month'] = pd.Series("DUMMY", dtype="string[pyarrow]")
dtypes['partition_year_month'] = pa.string()
df = pd.DataFrame(data=dummy)
write_deltalake("abfs://featurestore/test", df, partition_by=['bucket','partition_year_month'], schema=pa.schema(dtypes), mode="overwrite")
dt = DeltaTable("abfs://featurestore/test")
```
```
version = merge(dt, generate_random_data(10000).to_reader(1000), ['state', 'ts', 'bucket', 'partition_year_month'])
dt = DeltaTable("abfs://featurestore/test", version=version)
merge(dt, generate_random_data(10000).to_reader(10000), ['state', 'ts', 'bucket', 'partition_year_month'])
```
```
---------------------------------------------------------------------------
CommitFailedError Traceback (most recent call last)
Cell In[90], [line 1](vscode-notebook-cell:?execution_count=90&line=1)
----> [1](vscode-notebook-cell:?execution_count=90&line=1) merge(dt, generate_random_data(10000).to_reader(10000), ['state', 'ts', 'bucket', 'partition_year_month'])
Cell In[81], [line 26](vscode-notebook-cell:?execution_count=81&line=26)
[23](vscode-notebook-cell:?execution_count=81&line=23) if insert:
[24](vscode-notebook-cell:?execution_count=81&line=24) merger = merger.when_not_matched_insert_all()
---> [26](vscode-notebook-cell:?execution_count=81&line=26) log.info(merger.execute())
[27](vscode-notebook-cell:?execution_count=81&line=27) except StopIteration:
[28](vscode-notebook-cell:?execution_count=81&line=28) log.info("Finished all batches")
File ~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1793, in TableMerger.execute(self)
[1787](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1787) def execute(self) -> Dict[str, Any]:
[1788](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1788) """Executes `MERGE` with the previously provided settings in Rust with Apache Datafusion query engine.
[1789](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1789)
[1790](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1790) Returns:
[1791](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1791) Dict: metrics
[1792](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1792) """
-> [1793](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1793) metrics = self._table.merge_execute(self._builder)
[1794](https://file+.vscode-resource.vscode-cdn.net/Users/nfoerster/Repos/mono/cpm/pre_processing/~/Repos/mono/.venv/lib/python3.12/site-packages/deltalake/table.py:1794) return json.loads(metrics)
CommitFailedError: Failed to commit transaction: Error evaluating predicate: Generic DeltaTable error: Internal error: arrow_cast should have been simplified to cast.
This was likely caused by a bug in DataFusion's code and we would welcome that you file an bug report in our issue tracker
```
### Expected behavior
No error while using merger
### Additional context
adlfs==2024.7.0
agate==1.9.1
aiohttp==3.9.5
aiosignal==1.3.1
annotated-types==0.7.0
antlr4-python3-runtime==4.9.3
appnope==0.1.4
artifacts-keyring==0.3.6
asttokens==2.4.1
attrs==23.2.0
azure-common==1.1.28
azure-core==1.30.2
azure-datalake-store==0.0.53
azure-identity==1.15.0
azure-keyvault-secrets==4.8.0
azure-mgmt-core==1.4.0
azure-storage-blob==12.19.0
azureml-mlflow==1.56.0
babel==2.16.0
bcrypt==4.1.3
black==24.4.2
black-junit==0.2.4
cachetools==5.3.3
certifi==2024.6.2
cffi==1.16.0
cfgv==3.4.0
charset-normalizer==3.3.2
click==8.1.7
cloudpickle==3.0.0
colorama==0.4.6
comm==0.2.2
contourpy==1.2.1
cryptography==42.0.8
cycler==0.12.1
daff==1.3.46
dbt-adapters==1.6.1
dbt-common==1.8.0
dbt-core==1.8.6
dbt-duckdb==1.8.4
dbt-extractor==0.5.1
dbt-semantic-interfaces==0.5.1
debugpy==1.8.5
decorator==5.1.1
deepdiff==7.0.1
deltalake==0.20.0
Deprecated==1.2.14
distlib==0.3.8
duckdb==1.1.1
duckdb_deltalake_dbt==0.2.3rc14
entrypoints==0.4
executing==2.0.1
filelock==3.14.0
flake8==6.1.0
flake8-forbidden-func==0.1.0
flake8-formatter-junit-xml==0.0.6
fonttools==4.53.0
frozenlist==1.4.1
fsspec==2024.9.0
gitdb==4.0.11
GitPython==3.1.43
hydra-core==1.3.2
identify==2.5.36
idna==3.7
imbalanced-learn==0.12.3
importlib-metadata==6.11.0
importlib_resources==6.4.0
iniconfig==2.0.0
ipykernel==6.29.5
ipython==8.25.0
isodate==0.6.1
isort==5.13.2
jaraco.classes==3.4.0
jaraco.context==6.0.1
jaraco.functools==4.0.2
jedi==0.19.1
Jinja2==3.1.4
joblib==1.4.2
jsonpickle==3.2.1
jsonschema==4.23.0
jsonschema-specifications==2023.12.1
junit-xml==1.9
jupyter_client==8.6.3
jupyter_core==5.7.2
keyring==25.4.0
kiwisolver==1.4.5
leather==0.4.0
llvmlite==0.42.0
Logbook==1.5.3
loguru==0.7.2
MarkupSafe==2.1.5
mashumaro==3.13.1
matplotlib==3.9.0
matplotlib-inline==0.1.7
mccabe==0.7.0
minimal-snowplow-tracker==0.0.2
mlflow-skinny==2.13.2
more-itertools==10.5.0
msal==1.28.0
msal-extensions==1.1.0
msgpack==1.1.0
msrest==0.7.1
multidict==6.0.5
multimethod==1.10
mypy-extensions==1.0.0
natsort==8.4.0
nest-asyncio==1.6.0
networkx==3.3
nodeenv==1.9.1
numba==0.59.1
numpy==1.26.4
oauthlib==3.2.2
omegaconf==2.3.0
opentelemetry-api==1.25.0
opentelemetry-sdk==1.25.0
opentelemetry-semantic-conventions==0.46b0
ordered-set==4.1.0
packaging==24.1
pandas==2.0.3
pandera==0.19.3
paramiko==3.4.0
parsedatetime==2.6
parso==0.8.4
pathspec==0.12.1
pexpect==4.9.0
pillow==10.3.0
platformdirs==4.2.2
plotly==5.22.0
pluggy==1.5.0
polars==0.18.15
portalocker==2.8.2
pre-commit==3.7.1
prompt_toolkit==3.0.47
protobuf==4.25.3
psutil==6.0.0
psycopg2-binary==2.9.9
ptyprocess==0.7.0
pure-eval==0.2.2
pyaml==24.4.0
pyarrow==17.0.0
pyarrow-hotfix==0.6
pycodestyle==2.11.1
pycparser==2.22
pydantic==2.7.3
pydantic_core==2.18.4
pyflakes==3.1.0
Pygments==2.18.0
PyJWT==2.8.0
PyNaCl==1.5.0
pyparsing==3.1.2
pytest==7.4.4
pytest-azurepipelines==1.0.5
pytest-isort==3.1.0
pytest-lazy-fixture==0.6.3
pytest-nunit==1.0.7
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-slugify==8.0.4
pytimeparse==1.1.8
pytz==2024.1
PyYAML==6.0.1
pyzmq==26.2.0
referencing==0.35.1
regex==2023.12.25
requests==2.32.3
requests-oauthlib==2.0.0
rpds-py==0.20.0
scikit-learn==1.3.0
scikit-optimize==0.9.0
scipy==1.13.1
seaborn==0.12.2
setuptools==70.0.0
shap==0.42.1
six==1.16.0
slicer==0.0.7
smmap==5.0.1
SQLAlchemy==2.0.30
sqlparse==0.5.0
stack-data==0.6.3
tenacity==8.3.0
text-unidecode==1.3
threadpoolctl==3.5.0
tokenize-rt==5.2.0
tornado==6.4.1
tqdm==4.66.4
traitlets==5.14.3
trino==0.328.0
typeguard==4.3.0
types-regex==2023.12.25.20240311
typing-inspect==0.9.0
typing_extensions==4.12.2
tzdata==2024.1
tzlocal==5.2
universal_pathlib==0.2.2
urllib3==2.2.1
virtualenv==20.26.2
wcwidth==0.2.13
Werkzeug==3.0.3
wrapt==1.16.0
xgboost==1.7.6
yarl==1.9.4
zipp==3.19.2
Contributor guide
Research direction
Start by reproducing the failure with the provided Python setup, focusing on the second merger.execute() call and its multi-column predicate. Trace DataFusion's predicate evaluation and arrow_cast simplification; done means the second MERGE completes without the CommitFailedError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100