Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,13 @@ pub async fn handle_json_build_function(
}

// For other build functions or on failure, return Any
ctx
.ts_query
.insert_result(Some(ctx.alias), &[TsFieldType::Any], ctx.is_selection, false, expr_log)
ctx.ts_query.insert_result(
Some(ctx.alias),
&[TsFieldType::Unknown],
ctx.is_selection,
false,
expr_log,
)
Comment on lines 149 to +156
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says this fallback "return[s] Any", but the implementation now returns TsFieldType::Unknown. Please update the comment to avoid misleading readers.

Copilot uses AI. Check for mistakes.
}

/// Handle JSON aggregation functions (jsonb_agg, json_agg, etc.)
Expand Down
10 changes: 5 additions & 5 deletions src/ts_generator/sql_parser/expressions/translate_data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ pub fn translate_data_type(data_type: &DataType) -> TsFieldType {
DataType::Datetime64(_, _) => TsFieldType::Date,
DataType::Timestamp(_, _) => TsFieldType::String,
DataType::TimestampNtz => TsFieldType::String,
DataType::Interval { .. } => TsFieldType::Any,
DataType::Interval { .. } => TsFieldType::Unknown,

// JSON types
DataType::JSON => TsFieldType::Object,
Expand All @@ -151,9 +151,9 @@ pub fn translate_data_type(data_type: &DataType) -> TsFieldType {
DataType::TsQuery => TsFieldType::String,

// Complex types
DataType::Custom(_, _) => TsFieldType::Any,
DataType::Custom(_, _) => TsFieldType::Unknown,
DataType::Array(array_element_type_def) => match array_element_type_def {
sqlparser::ast::ArrayElemTypeDef::None => TsFieldType::Array(Box::new(TsFieldType::Any)),
sqlparser::ast::ArrayElemTypeDef::None => TsFieldType::Array(Box::new(TsFieldType::Unknown)),
sqlparser::ast::ArrayElemTypeDef::AngleBracket(data_type) => {
TsFieldType::Array(Box::new(translate_data_type(data_type)))
}
Expand All @@ -177,8 +177,8 @@ pub fn translate_data_type(data_type: &DataType) -> TsFieldType {
DataType::LowCardinality(inner_type) => translate_data_type(inner_type),

// Special types
DataType::Unspecified => TsFieldType::Any,
DataType::Trigger => TsFieldType::Any,
DataType::Unspecified => TsFieldType::Unknown,
DataType::Trigger => TsFieldType::Unknown,
DataType::AnyType => TsFieldType::Any,
}
}
48 changes: 34 additions & 14 deletions src/ts_generator/sql_parser/expressions/translate_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,13 +485,13 @@ pub async fn translate_expr(
ts_query.insert_param(&inferred_type, &false, &Some(placeholder.to_string()))
}
Expr::JsonAccess { value: _, path: _ } => {
ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging)?;
ts_query.insert_param(&TsFieldType::Any, &false, &None)
ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging)?;
ts_query.insert_param(&TsFieldType::Unknown, &false, &None)
}
Comment on lines 487 to 490
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR replaces many Any fallbacks with Unknown, but Expr::Value still falls back to TsFieldType::Any when it can’t infer a literal’s type (see the inferred_type assignment just above this hunk). If the intent is to avoid emitting any for unknown types, consider switching that fallback to TsFieldType::Unknown as well (keeping the Boolean special-case if needed).

Copilot uses AI. Check for mistakes.
Expr::IsNotDistinctFrom(_, placeholder) | Expr::IsDistinctFrom(_, placeholder) => {
// IsDistinctFrom and IsNotDistinctFrom are the same and can have a placeholder
ts_query.insert_param(&TsFieldType::String, &false, &Some(placeholder.to_string()))?;
ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging)
ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging)
}
Expr::SimilarTo {
negated: _,
Expand Down Expand Up @@ -577,10 +577,12 @@ pub async fn translate_expr(
ts_query.insert_result(alias, &[TsFieldType::String], is_selection, false, expr_for_logging)
}
Expr::Collate { expr: _, collation: _ } => {
ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging)
ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging)
}
Expr::TypedString(_) => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
Expr::Map(_) => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
Expr::TypedString(_) => {
ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging)
}
Expr::Map(_) => ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging),
// Note: AggregateExpressionWithFilter was removed in sqlparser 0.59.0
// Aggregate functions with filters are now part of the Function variant
Expr::Case {
Expand All @@ -589,22 +591,22 @@ pub async fn translate_expr(
else_result: _,
case_token: _,
end_token: _,
} => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
} => ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging),
Expr::Exists { subquery, negated: _ } => {
ts_query.insert_result(alias, &[TsFieldType::Boolean], is_selection, false, expr_for_logging)?;
translate_query(ts_query, &None, subquery, db_conn, alias, false).await
}
// Note: ListAgg and ArrayAgg were removed in sqlparser 0.59.0
// They are now represented as Function variants
Expr::GroupingSets(_) | Expr::Cube(_) | Expr::Rollup(_) | Expr::Tuple(_) | Expr::Array(_) => {
ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging)
ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging)
}
// Note: ArrayIndex was replaced with CompoundFieldAccess in sqlparser 0.59.0
// CompoundFieldAccess handles array indexing, map access, and composite field access
Expr::CompoundFieldAccess {
root: _,
access_chain: _,
} => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
} => ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging),
Expr::Interval(_) => ts_query.insert_result(alias, &[TsFieldType::Number], is_selection, false, expr_for_logging),
Expr::MatchAgainst {
columns: _,
Expand Down Expand Up @@ -655,7 +657,13 @@ pub async fn translate_expr(
FunctionArguments::List(arg_list) => &arg_list.args,
_ => {
// If no arguments or subquery, return Any
return ts_query.insert_result(Some(alias), &[TsFieldType::Any], is_selection, false, expr_for_logging);
return ts_query.insert_result(
Some(alias),
&[TsFieldType::Unknown],
is_selection,
Comment on lines 658 to +663
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "return Any" but this branch now returns TsFieldType::Unknown. Please update the comment to match the behavior (or revert the behavior if Any was intended here).

Copilot uses AI. Check for mistakes.
false,
expr_for_logging,
);
}
};

Expand All @@ -680,7 +688,13 @@ pub async fn translate_expr(
FunctionArguments::List(arg_list) => &arg_list.args,
_ => {
// If no arguments or subquery, return Any
return ts_query.insert_result(Some(alias), &[TsFieldType::Any], is_selection, false, expr_for_logging);
return ts_query.insert_result(
Some(alias),
&[TsFieldType::Unknown],
is_selection,
Comment on lines 689 to +694
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment says "return Any" but the code now falls back to TsFieldType::Unknown. Please update the comment so it accurately reflects the fallback type.

Copilot uses AI. Check for mistakes.
false,
expr_for_logging,
);
}
};

Expand Down Expand Up @@ -723,7 +737,13 @@ pub async fn translate_expr(
expr_for_logging,
)?;
} else {
ts_query.insert_result(Some(alias), &[TsFieldType::Any], is_selection, false, expr_for_logging)?;
ts_query.insert_result(
Some(alias),
&[TsFieldType::Unknown],
is_selection,
false,
expr_for_logging,
)?;
}

Ok(())
Expand Down Expand Up @@ -756,8 +776,8 @@ pub async fn translate_expr(
expr: _,
array_expr: _,
negated: _,
} => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
_ => ts_query.insert_result(alias, &[TsFieldType::Any], is_selection, false, expr_for_logging),
} => ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging),
_ => ts_query.insert_result(alias, &[TsFieldType::Unknown], is_selection, false, expr_for_logging),
}
}

Expand Down
14 changes: 8 additions & 6 deletions src/ts_generator/types/ts_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub enum TsFieldType {
Null,
Enum(Vec<String>),
Any,
Unknown,
#[allow(dead_code)]
Array2D(Array2DContent),
Array(Box<TsFieldType>),
Expand Down Expand Up @@ -149,6 +150,7 @@ impl fmt::Display for TsFieldType {
TsFieldType::Any => write!(f, "any"),
TsFieldType::Null => write!(f, "null"),
TsFieldType::Never => write!(f, "never"),
TsFieldType::Unknown => write!(f, "unknown"),
TsFieldType::Array(ts_field_type) => {
let ts_field_type = ts_field_type.clone();
let ts_field_type = *ts_field_type;
Expand Down Expand Up @@ -201,17 +203,17 @@ impl TsFieldType {
"character" | "character varying" | "bytea" | "uuid" | "text" => Self::String,
"boolean" => Self::Boolean,
"json" | "jsonb" => Self::Object,
"ARRAY" | "array" => Self::Any,
"ARRAY" | "array" => Self::Unknown,
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping PostgreSQL data_type = ARRAY directly to TsFieldType::Unknown loses the fact that the value is an array. Consider mapping this to an array type with unknown element type (e.g., Array<unknown> / TsFieldType::Array(Box::new(TsFieldType::Unknown))) so callers still get correct array shape while retaining safety.

Suggested change
"ARRAY" | "array" => Self::Unknown,
"ARRAY" | "array" => Self::Array(Box::new(Self::Unknown)),

Copilot uses AI. Check for mistakes.
"date" => Self::Date,
"USER-DEFINED" => {
if let Some(enum_values) = enum_values {
return Self::Enum(enum_values);
}
let warning_message = format!("Failed to find enum values for field {field_name} of table {table_name}");
warning!(warning_message);
Self::Any
Self::Unknown
}
_ => Self::Any,
_ => Self::Unknown,
}
}

Expand All @@ -234,9 +236,9 @@ impl TsFieldType {

let warning_message = format!("Failed to find enum values for field {field_name} of table {table_name}");
warning!(warning_message);
Self::Any
Self::Unknown
}
_ => Self::Any,
_ => Self::Unknown,
}
}

Expand All @@ -252,7 +254,7 @@ impl TsFieldType {
} else if annotated_type == "null" {
return Self::Null;
}
Self::Any
Self::Unknown
}

/// Converts a sqlparser DataType from table alias column definitions to TsFieldType
Expand Down
4 changes: 2 additions & 2 deletions tests/demo/aggregate_functions/basic_aggregates.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export type StddevAndVarianceParams = [];

export interface IStddevAndVarianceResult {
rarity: string | null;
stddevId: any;
varianceId: any;
stddevId: unknown;
varianceId: unknown;
}

export interface IStddevAndVarianceQuery {
Expand Down
4 changes: 2 additions & 2 deletions tests/demo/aggregate_functions/basic_aggregates.snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export type StddevAndVarianceParams = [];

export interface IStddevAndVarianceResult {
rarity: string | null;
stddevId: any;
varianceId: any;
stddevId: unknown;
varianceId: unknown;
}

export interface IStddevAndVarianceQuery {
Expand Down
2 changes: 1 addition & 1 deletion tests/demo/case_expressions/case_in_clauses.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type CaseInGroupByHavingParams = [];

export interface ICaseInGroupByHavingResult {
count: number;
rarityGroup: any;
rarityGroup: unknown;
}

export interface ICaseInGroupByHavingQuery {
Expand Down
2 changes: 1 addition & 1 deletion tests/demo/case_expressions/case_in_clauses.snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type CaseInGroupByHavingParams = [];

export interface ICaseInGroupByHavingResult {
count: number;
rarityGroup: any;
rarityGroup: unknown;
}

export interface ICaseInGroupByHavingQuery {
Expand Down
4 changes: 2 additions & 2 deletions tests/demo/case_expressions/nested_case.queries.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type NestedCaseBasicParams = [];

export interface INestedCaseBasicResult {
detailedRarity: any;
detailedRarity: unknown;
id: number;
name: string;
rarity: string | null;
Expand All @@ -17,7 +17,7 @@ export type NestedCaseMultipleLevelsParams = [];
export interface INestedCaseMultipleLevelsResult {
id: number;
name: string;
tier: any;
tier: unknown;
}

export interface INestedCaseMultipleLevelsQuery {
Expand Down
4 changes: 2 additions & 2 deletions tests/demo/case_expressions/nested_case.snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type NestedCaseBasicParams = [];

export interface INestedCaseBasicResult {
detailedRarity: any;
detailedRarity: unknown;
id: number;
name: string;
rarity: string | null;
Expand All @@ -17,7 +17,7 @@ export type NestedCaseMultipleLevelsParams = [];
export interface INestedCaseMultipleLevelsResult {
id: number;
name: string;
tier: any;
tier: unknown;
}

export interface INestedCaseMultipleLevelsQuery {
Expand Down
6 changes: 3 additions & 3 deletions tests/demo/case_expressions/searched_case.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export type SearchedCaseBasicParams = [];

export interface ISearchedCaseBasicResult {
id: number;
idCategory: any;
idCategory: unknown;
name: string;
}

Expand All @@ -15,7 +15,7 @@ export type SearchedCaseMultipleConditionsParams = [];

export interface ISearchedCaseMultipleConditionsResult {
id: number;
itemClass: any;
itemClass: unknown;
name: string;
rarity: string | null;
}
Expand All @@ -30,7 +30,7 @@ export type SearchedCaseWithParamsParams = [];
export interface ISearchedCaseWithParamsResult {
id: number;
name: string;
thresholdStatus: any;
thresholdStatus: unknown;
}

export interface ISearchedCaseWithParamsQuery {
Expand Down
6 changes: 3 additions & 3 deletions tests/demo/case_expressions/searched_case.snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export type SearchedCaseBasicParams = [];

export interface ISearchedCaseBasicResult {
id: number;
idCategory: any;
idCategory: unknown;
name: string;
}

Expand All @@ -15,7 +15,7 @@ export type SearchedCaseMultipleConditionsParams = [];

export interface ISearchedCaseMultipleConditionsResult {
id: number;
itemClass: any;
itemClass: unknown;
name: string;
rarity: string | null;
}
Expand All @@ -30,7 +30,7 @@ export type SearchedCaseWithParamsParams = [];
export interface ISearchedCaseWithParamsResult {
id: number;
name: string;
thresholdStatus: any;
thresholdStatus: unknown;
}

export interface ISearchedCaseWithParamsQuery {
Expand Down
8 changes: 4 additions & 4 deletions tests/demo/case_expressions/simple_case.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export type SimpleCaseBasicParams = [];
export interface ISimpleCaseBasicResult {
id: number;
name: string;
rarityCode: any;
rarityCode: unknown;
}

export interface ISimpleCaseBasicQuery {
Expand All @@ -16,7 +16,7 @@ export type SimpleCaseWithNullParams = [];
export interface ISimpleCaseWithNullResult {
id: number;
name: string;
rarityLevel: any;
rarityLevel: unknown;
}

export interface ISimpleCaseWithNullQuery {
Expand All @@ -28,9 +28,9 @@ export type MultipleCaseExpressionsParams = [];

export interface IMultipleCaseExpressionsResult {
id: number;
idRange: any;
idRange: unknown;
name: string;
rarityTier: any;
rarityTier: unknown;
}

export interface IMultipleCaseExpressionsQuery {
Expand Down
Loading
Loading