should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,143 @@
import os
import json
import re
import glob
import copy
from packaging.version import Version
from functools import reduce
from pathlib import Path
EXT_API_DEFINITION_PATTERN = "src/include/duckdb/main/capi/header_generation/apis/v1/*/*.json"
# The JSON files that define all available CAPI functions
CAPI_FUNCTION_DEFINITION_FILES = 'src/include/duckdb/main/capi/header_generation/functions/**/*.json'
# The original order of the function groups in the duckdb.h files. We maintain this for easier PR reviews.
# TODO: replace this with alphabetical ordering in a separate PR
ORIGINAL_FUNCTION_GROUP_ORDER = [
'open_connect',
'configuration',
'query_execution',
'result_functions',
'safe_fetch_functions',
'helpers',
'date_time_timestamp_helpers',
'hugeint_helpers',
'unsigned_hugeint_helpers',
'decimal_helpers',
'prepared_statements',
'bind_values_to_prepared_statements',
'execute_prepared_statements',
'extract_statements',
'pending_result_interface',
'value_interface',
'logical_type_interface',
'data_chunk_interface',
'vector_interface',
'validity_mask_functions',
'scalar_functions',
'aggregate_functions',
'table_functions',
'table_function_bind',
'table_function_init',
'table_function',
'replacement_scans',
'profiling_info',
'appender',
'table_description',
'arrow_interface',
'threading_information',
'streaming_result_interface',
'cast_functions',
'expression_interface',
]
def get_extension_api_version(ext_api_definitions):
latest_version = ""
for version_entry in ext_api_definitions:
if version_entry["version"].startswith("v"):
latest_version = version_entry["version"]
if version_entry["version"].startswith("unstable_"):
break
return latest_version
# Parse the CAPI_FUNCTION_DEFINITION_FILES to get the full list of functions
def parse_capi_function_definitions(function_definition_file_pattern):
# Collect all functions
# function_files = glob.glob(CAPI_FUNCTION_DEFINITION_FILES, recursive=True)
function_files = glob.glob(function_definition_file_pattern, recursive=True)
function_groups = []
function_map = {}
# Read functions
for file in function_files:
with open(file, "r") as f:
try:
json_data = json.loads(f.read())
except json.decoder.JSONDecodeError as err:
print(f"Invalid JSON found in {file}: {err}")
exit(1)
function_groups.append(json_data)
for function in json_data["entries"]:
if function["name"] in function_map:
print(f"Duplicate symbol found when parsing C API file {file}: {function['name']}")
exit(1)
function["group"] = json_data["group"]
if "deprecated" in json_data:
function["group_deprecated"] = json_data["deprecated"]
function_map[function["name"]] = function
# Reorder to match original order: purely intended to keep the PR review sane
function_groups_ordered = []
if len(function_groups) != len(ORIGINAL_FUNCTION_GROUP_ORDER):
print(
"The list used to match the original order of function groups in the original the duckdb.h file does not match the new one. Did you add a new function group? please also add it to ORIGINAL_FUNCTION_GROUP_ORDER for now."
)
for order_group in ORIGINAL_FUNCTION_GROUP_ORDER:
curr_group = next(group for group in function_groups if group["group"] == order_group)
function_groups.remove(curr_group)
function_groups_ordered.append(curr_group)
return (function_groups_ordered, function_map)
# Read extension API
def parse_ext_api_definitions(ext_api_definition):
api_definitions = {}
versions = []
dev_versions = []
for file in list(glob.glob(ext_api_definition)):
with open(file, "r") as f:
try:
obj = json.loads(f.read())
api_definitions[obj["version"]] = obj
if obj["version"].startswith("unstable_"):
dev_versions.append(obj["version"])
else:
if Path(file).stem != obj["version"]:
print(
f"\nMismatch between filename and version in file for {file}. Note that unstable versions should have a version starting with 'unstable_' and that stable versions should have the version as their filename"
)
exit(1)
versions.append(obj["version"])
except json.decoder.JSONDecodeError as err:
print(f"\nInvalid JSON found in {file}: {err}")
exit(1)
versions.sort(key=Version)
dev_versions.sort()
return [api_definitions[x] for x in (versions + dev_versions)]