MCPcopy Create free account
hub / github.com/PRQL/prql / try_extract_sql_columns

Function try_extract_sql_columns

prqlc/prqlc/src/semantic/lowering.rs:1045–1133  ·  view source on GitHub ↗

Attempts to extract column names from an S-String to avoid wildcards when possible

(
    columns: Vec<RelationColumn>,
    items: &[InterpolateItem<rq::Expr>],
)

Source from the content-addressed store, hash-verified

1043
1044/// Attempts to extract column names from an S-String to avoid wildcards when possible
1045fn try_extract_sql_columns(
1046 columns: Vec<RelationColumn>,
1047 items: &[InterpolateItem<rq::Expr>],
1048) -> Vec<RelationColumn> {
1049 use sqlparser::ast;
1050
1051 let mut has_wildcard = false;
1052
1053 let sql_columns = items
1054 .iter()
1055 .map(|item| match item {
1056 InterpolateItem::String(s) => {
1057 let sql_ast =
1058 sqlparser::parser::Parser::parse_sql(&sqlparser::dialect::GenericDialect {}, s)
1059 .map_err(|err| format!("could not parse {item:?}: {err:?}"))?;
1060 if sql_ast.len() != 1 {
1061 return Err(format!(
1062 "expected exactly one statement, got {}",
1063 sql_ast.len()
1064 ));
1065 }
1066
1067 let statement = sql_ast.into_iter().next().unwrap();
1068
1069 if let sqlparser::ast::Statement::Query(query) = statement {
1070 if let sqlparser::ast::SetExpr::Select(select_stmt) = *query.body {
1071 select_stmt
1072 .projection
1073 .into_iter()
1074 .map(|expr| match expr {
1075 ast::SelectItem::UnnamedExpr(expr) => {
1076 if let ast::Expr::Identifier(ast::Ident { value, .. }) = expr {
1077 Ok(value)
1078 } else {
1079 Err(format!("Only Idents are supported, got {expr:?}"))
1080 }
1081 }
1082 ast::SelectItem::ExprWithAlias { alias, .. } => Ok(alias.value), // Store alias
1083 ast::SelectItem::ExprWithAliases { .. } => Err(
1084 "Multi-alias projection (`expr AS (a, b)`) is not supported"
1085 .into(),
1086 ),
1087 ast::SelectItem::QualifiedWildcard(_, _)
1088 | ast::SelectItem::Wildcard(_) => {
1089 has_wildcard = true;
1090 Err("columns contain a wildcard".into())
1091 }
1092 })
1093 .collect::<Result<Vec<String>, String>>()
1094 } else {
1095 Err(format!("not a SELECT statement: {query:?}"))
1096 }
1097 } else {
1098 Err(format!("not a Query: {statement:?}"))
1099 }
1100 }
1101 InterpolateItem::Expr { .. } => Err(format!(
1102 "could not extract columns from item {item:?}: not a string"

Callers 1

lower_table_refMethod · 0.85

Calls 6

mapMethod · 0.80
iterMethod · 0.80
lenMethod · 0.80
nextMethod · 0.80
into_iterMethod · 0.80
collectMethod · 0.45

Tested by

no test coverage detected