amaye15 commited on
Commit
850182e
·
1 Parent(s): 3bcb6cf
Files changed (1) hide show
  1. main.py +54 -21
main.py CHANGED
@@ -91,36 +91,69 @@ class ApiResponse(BaseModel):
91
  message: str
92
  details: Optional[Any] = None
93
 
94
- # --- Helper Functions (keep existing) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  def safe_identifier(name: str) -> str:
96
- """Quotes an identifier safely using DuckDB."""
97
  if not name or not isinstance(name, str):
98
  raise HTTPException(status_code=400, detail=f"Invalid identifier provided: {name}")
99
- try:
100
- with duckdb.connect(':memory:') as temp_conn:
101
- quoted = temp_conn.sql(f"SELECT '{name}'::IDENTIFIER").fetchone()
102
- if quoted:
103
- return quoted[0]
104
- else:
105
- raise HTTPException(status_code=500, detail="Failed to quote identifier")
106
- except duckdb.Error as e:
107
- logger.error(f"Error quoting identifier '{name}': {e}")
108
- raise HTTPException(status_code=400, detail=f"Invalid identifier '{name}': {e}")
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  def generate_column_sql(columns: List[ColumnDefinition]) -> str:
111
  """Generates the column definition part of a CREATE TABLE statement."""
112
  defs = []
113
  for col in columns:
114
  col_name_safe = safe_identifier(col.name)
115
- allowed_types_prefix = ['INTEGER', 'VARCHAR', 'TEXT', 'BOOLEAN', 'FLOAT', 'DOUBLE', 'DATE', 'TIMESTAMP', 'BLOB', 'BIGINT', 'DECIMAL', 'LIST', 'STRUCT', 'MAP', 'UNION']
116
- type_upper = col.type.strip().upper()
117
- is_allowed = False
118
- for prefix in allowed_types_prefix:
119
- if type_upper.startswith(prefix):
120
- is_allowed = True
121
- break
122
- if not is_allowed:
123
- raise HTTPException(status_code=400, detail=f"Unsupported or potentially invalid data type: {col.type}")
 
 
 
 
 
124
  defs.append(f"{col_name_safe} {col.type}")
125
  return ", ".join(defs)
126
 
 
91
  message: str
92
  details: Optional[Any] = None
93
 
94
+ # # --- Helper Functions (keep existing) ---
95
+ # def safe_identifier(name: str) -> str:
96
+ # """Quotes an identifier safely using DuckDB."""
97
+ # if not name or not isinstance(name, str):
98
+ # raise HTTPException(status_code=400, detail=f"Invalid identifier provided: {name}")
99
+ # try:
100
+ # with duckdb.connect(':memory:') as temp_conn:
101
+ # quoted = temp_conn.sql(f"SELECT '{name}'::IDENTIFIER").fetchone()
102
+ # if quoted:
103
+ # return quoted[0]
104
+ # else:
105
+ # raise HTTPException(status_code=500, detail="Failed to quote identifier")
106
+ # except duckdb.Error as e:
107
+ # logger.error(f"Error quoting identifier '{name}': {e}")
108
+ # raise HTTPException(status_code=400, detail=f"Invalid identifier '{name}': {e}")
109
+
110
+
111
  def safe_identifier(name: str) -> str:
112
+ """Quotes an identifier safely for DuckDB SQL."""
113
  if not name or not isinstance(name, str):
114
  raise HTTPException(status_code=400, detail=f"Invalid identifier provided: {name}")
115
+ # Escape any double quotes within the identifier itself
116
+ escaped_name = name.replace('"', '""')
117
+ # Always enclose in double quotes for safety, especially with keywords or special chars
118
+ return f'"{escaped_name}"'
119
+
120
+
121
+ # def generate_column_sql(columns: List[ColumnDefinition]) -> str:
122
+ # """Generates the column definition part of a CREATE TABLE statement."""
123
+ # defs = []
124
+ # for col in columns:
125
+ # col_name_safe = safe_identifier(col.name)
126
+ # allowed_types_prefix = ['INTEGER', 'VARCHAR', 'TEXT', 'BOOLEAN', 'FLOAT', 'DOUBLE', 'DATE', 'TIMESTAMP', 'BLOB', 'BIGINT', 'DECIMAL', 'LIST', 'STRUCT', 'MAP', 'UNION']
127
+ # type_upper = col.type.strip().upper()
128
+ # is_allowed = False
129
+ # for prefix in allowed_types_prefix:
130
+ # if type_upper.startswith(prefix):
131
+ # is_allowed = True
132
+ # break
133
+ # if not is_allowed:
134
+ # raise HTTPException(status_code=400, detail=f"Unsupported or potentially invalid data type: {col.type}")
135
+ # defs.append(f"{col_name_safe} {col.type}")
136
+ # return ", ".join(defs)
137
 
138
  def generate_column_sql(columns: List[ColumnDefinition]) -> str:
139
  """Generates the column definition part of a CREATE TABLE statement."""
140
  defs = []
141
  for col in columns:
142
  col_name_safe = safe_identifier(col.name)
143
+ # --- REMOVE OR COMMENT OUT THE STRICT VALIDATION ---
144
+ # allowed_types_prefix = ['INTEGER', 'VARCHAR', 'TEXT', 'BOOLEAN', 'FLOAT', 'DOUBLE', 'DATE', 'TIMESTAMP', 'BLOB', 'BIGINT', 'DECIMAL', 'LIST', 'STRUCT', 'MAP', 'UNION']
145
+ # type_upper = col.type.strip().upper()
146
+ # is_allowed = False
147
+ # for prefix in allowed_types_prefix:
148
+ # # Allow types like VARCHAR(255), DECIMAL(10,2), LIST<INT>, STRUCT<a INT> etc.
149
+ # if type_upper.startswith(prefix):
150
+ # is_allowed = True
151
+ # break
152
+ # if not is_allowed:
153
+ # raise HTTPException(status_code=400, detail=f"Unsupported or potentially invalid data type: {col.type}")
154
+ # --- END REMOVAL ---
155
+
156
+ # Trust DuckDB to validate the full type string including constraints
157
  defs.append(f"{col_name_safe} {col.type}")
158
  return ", ".join(defs)
159