Skip to content

Commit c23a635

Browse files
committed
progress
1 parent 212df5d commit c23a635

File tree

17 files changed

+305
-11
lines changed

17 files changed

+305
-11
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use pgt_query::protobuf::AConst;
2+
use pgt_query::protobuf::a_const::Val;
3+
4+
use crate::{
5+
TokenKind,
6+
emitter::{EventEmitter, GroupKind},
7+
};
8+
9+
pub(super) fn emit_a_const(e: &mut EventEmitter, n: &AConst) {
10+
e.group_start(GroupKind::AConst);
11+
12+
if n.isnull {
13+
e.token(TokenKind::NULL_KW);
14+
} else if let Some(ref val) = n.val {
15+
emit_val(e, val);
16+
} else {
17+
unreachable!("AConst must have either isnull=true or a val");
18+
}
19+
20+
e.group_end();
21+
}
22+
23+
fn emit_val(e: &mut EventEmitter, n: &Val) {
24+
match n {
25+
Val::Ival(integer) => {
26+
super::emit_integer(e, integer);
27+
}
28+
Val::Fval(float) => {
29+
super::emit_float(e, float);
30+
}
31+
Val::Boolval(boolean) => {
32+
super::emit_boolean(e, boolean);
33+
}
34+
Val::Sval(string) => {
35+
super::emit_string_literal(e, string);
36+
}
37+
Val::Bsval(bsval) => {
38+
super::emit_bitstring(e, bsval);
39+
}
40+
}
41+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use pgt_query::protobuf::{AExpr, AExprKind};
2+
3+
use crate::emitter::{EventEmitter, GroupKind};
4+
5+
pub(super) fn emit_a_expr(e: &mut EventEmitter, n: &AExpr) {
6+
e.group_start(GroupKind::AExpr);
7+
8+
assert_eq!(n.kind(), AExprKind::AexprOp);
9+
10+
if let Some(ref lexpr) = n.lexpr {
11+
super::emit_node(lexpr, e);
12+
}
13+
14+
if !n.name.is_empty() {
15+
e.space();
16+
for name in &n.name {
17+
super::emit_node(name, e);
18+
}
19+
e.space();
20+
}
21+
22+
if let Some(ref rexpr) = n.rexpr {
23+
super::emit_node(rexpr, e);
24+
}
25+
26+
e.group_end();
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use pgt_query::protobuf::AStar;
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
};
7+
8+
pub(super) fn emit_a_star(e: &mut EventEmitter, _n: &AStar) {
9+
e.token(TokenKind::IDENT("*".to_string()))
10+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use pgt_query::protobuf::BitString;
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
};
7+
8+
pub(super) fn emit_bitstring(e: &mut EventEmitter, n: &BitString) {
9+
e.group_start(GroupKind::BitString);
10+
// The bsval contains the bit string value including any prefix
11+
// For binary strings: "b..." or "B..."
12+
// For hex strings: "x..." or "X..."
13+
if n.bsval.starts_with("b'")
14+
|| n.bsval.starts_with("B'")
15+
|| n.bsval.starts_with("x'")
16+
|| n.bsval.starts_with("X'")
17+
{
18+
e.token(TokenKind::STRING(n.bsval.to_uppercase()));
19+
} else if n.bsval.starts_with('b') || n.bsval.starts_with('B') {
20+
// Handle binary without quotes
21+
let digits = &n.bsval[1..];
22+
e.token(TokenKind::STRING(format!("B'{}'", digits)));
23+
} else if n.bsval.starts_with('x') || n.bsval.starts_with('X') {
24+
// Handle hex without quotes
25+
let digits = &n.bsval[1..];
26+
e.token(TokenKind::STRING(format!("X'{}'", digits)));
27+
} else {
28+
// Default to binary if no prefix
29+
e.token(TokenKind::STRING(format!("B'{}'", n.bsval)));
30+
}
31+
e.group_end();
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use pgt_query::protobuf::{BoolExpr, BoolExprType};
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
nodes::node_list::emit_keyword_separated_list,
7+
};
8+
9+
pub(super) fn emit_bool_expr(e: &mut EventEmitter, n: &BoolExpr) {
10+
e.group_start(GroupKind::BoolExpr);
11+
12+
match n.boolop() {
13+
BoolExprType::AndExpr => emit_keyword_separated_list(e, &n.args, TokenKind::AND_KW),
14+
BoolExprType::OrExpr => emit_keyword_separated_list(e, &n.args, TokenKind::OR_KW),
15+
BoolExprType::NotExpr => {
16+
e.token(crate::TokenKind::NOT_KW);
17+
e.space();
18+
assert!(
19+
n.args.len() == 1,
20+
"NOT expressions should have exactly one argument"
21+
);
22+
let arg = &n.args[0];
23+
super::emit_node(arg, e);
24+
}
25+
BoolExprType::Undefined => unreachable!("Undefined BoolExprType"),
26+
}
27+
28+
e.group_end();
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use pgt_query::protobuf::Boolean;
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
};
7+
8+
pub(super) fn emit_boolean(e: &mut EventEmitter, n: &Boolean) {
9+
e.group_start(GroupKind::Boolean);
10+
// todo: user needs to be able to configure the case of boolean literals
11+
let val_str = if n.boolval { "TRUE" } else { "FALSE" };
12+
e.token(TokenKind::IDENT(val_str.to_string()));
13+
e.group_end();
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use pgt_query::protobuf::Float;
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
};
7+
8+
pub(super) fn emit_float(e: &mut EventEmitter, n: &Float) {
9+
e.group_start(GroupKind::Float);
10+
e.token(TokenKind::IDENT(n.fval.clone()));
11+
e.group_end();
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use pgt_query::protobuf::Integer;
2+
3+
use crate::{
4+
TokenKind,
5+
emitter::{EventEmitter, GroupKind},
6+
};
7+
8+
pub(super) fn emit_integer(e: &mut EventEmitter, n: &Integer) {
9+
e.group_start(GroupKind::Integer);
10+
e.token(TokenKind::IDENT(n.ival.to_string()));
11+
e.group_end();
12+
}

crates/pgt_pretty_print/src/nodes/mod.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
1+
mod a_const;
2+
mod a_expr;
3+
mod a_star;
4+
mod bitstring;
5+
mod bool_expr;
6+
mod boolean;
17
mod column_ref;
8+
mod float;
9+
mod integer;
210
mod node_list;
311
mod range_var;
412
mod res_target;
513
mod select_stmt;
614
mod string;
15+
mod update_stmt;
716

17+
use a_const::emit_a_const;
18+
use a_expr::emit_a_expr;
19+
use a_star::emit_a_star;
20+
use bitstring::emit_bitstring;
21+
use bool_expr::emit_bool_expr;
22+
use boolean::emit_boolean;
823
use column_ref::emit_column_ref;
24+
use float::emit_float;
25+
use integer::emit_integer;
926
use range_var::emit_range_var;
1027
use res_target::emit_res_target;
1128
use select_stmt::emit_select_stmt;
12-
use string::emit_string;
29+
use string::{emit_string, emit_string_identifier, emit_string_literal};
30+
use update_stmt::emit_update_stmt;
1331

1432
use crate::emitter::EventEmitter;
1533
use pgt_query::{NodeEnum, protobuf::Node};
@@ -23,10 +41,19 @@ pub fn emit_node(node: &Node, e: &mut EventEmitter) {
2341
pub fn emit_node_enum(node: &NodeEnum, e: &mut EventEmitter) {
2442
match &node {
2543
NodeEnum::SelectStmt(n) => emit_select_stmt(e, n),
44+
NodeEnum::UpdateStmt(n) => emit_update_stmt(e, n),
2645
NodeEnum::ResTarget(n) => emit_res_target(e, n),
2746
NodeEnum::ColumnRef(n) => emit_column_ref(e, n),
2847
NodeEnum::String(n) => emit_string(e, n),
2948
NodeEnum::RangeVar(n) => emit_range_var(e, n),
49+
NodeEnum::AConst(n) => emit_a_const(e, n),
50+
NodeEnum::Integer(n) => emit_integer(e, n),
51+
NodeEnum::Float(n) => emit_float(e, n),
52+
NodeEnum::Boolean(n) => emit_boolean(e, n),
53+
NodeEnum::BitString(n) => emit_bitstring(e, n),
54+
NodeEnum::AExpr(n) => emit_a_expr(e, n),
55+
NodeEnum::AStar(n) => emit_a_star(e, n),
56+
NodeEnum::BoolExpr(n) => emit_bool_expr(e, n),
3057
_ => todo!("emit_node_enum: unhandled node type {:?}", node),
3158
}
3259
}

crates/pgt_pretty_print/src/nodes/node_list.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,18 @@ pub(super) fn emit_dot_separated_list(e: &mut EventEmitter, nodes: &[Node]) {
2121
super::emit_node(n, e);
2222
}
2323
}
24+
25+
pub(super) fn emit_keyword_separated_list(
26+
e: &mut EventEmitter,
27+
nodes: &[Node],
28+
keyword: TokenKind,
29+
) {
30+
for (i, n) in nodes.iter().enumerate() {
31+
if i > 0 {
32+
e.space();
33+
e.token(keyword.clone());
34+
e.line(LineType::SoftOrSpace);
35+
}
36+
super::emit_node(n, e);
37+
}
38+
}

0 commit comments

Comments
 (0)