1use crate::parser::ast::types::DataType;
2use crate::parser::core::error::{ParseError, ParseErrorKind};
3use crate::parser::parsing::expr_parser::parse_expression;
4use crate::parser::parsing::parse_context::ParseContext;
5use crate::parser::TokenKind;
6use linkrs_core::types::PropertyDef;
7use linkrs_core::{ArrayTypeInfo, NullType, StructTypeInfo, Value};
8use std::sync::Arc;
9
10use super::DdlParser;
11
12impl DdlParser {
13 pub fn parse_property_defs(
14 &mut self,
15 ctx: &mut ParseContext,
16 ) -> Result<Vec<PropertyDef>, ParseError> {
17 let mut defs = Vec::new();
18 if ctx.match_token(TokenKind::LParen) {
19 while !ctx.check_token(TokenKind::RParen) {
20 let name = ctx.expect_identifier()?;
21 let _ = ctx.match_token(TokenKind::Colon);
22 let mut serial = false;
23 let dtype = if ctx.match_token(TokenKind::Serial) {
24 serial = true;
25 DataType::BigInt
26 } else {
27 self.parse_data_type(ctx)?
28 };
29 let mut nullable = true;
30 if ctx.check_token(TokenKind::Not) {
31 ctx.next_token();
32 if ctx.check_token(TokenKind::Null) {
33 ctx.next_token();
34 nullable = false;
35 }
36 } else if ctx.match_token(TokenKind::Null) {
37 nullable = true;
38 }
39 if serial {
40 nullable = false;
42 }
43 let mut default = None;
44 if ctx.match_token(TokenKind::Default) {
45 default = Some(self.parse_value_literal(ctx)?);
46 }
47 let mut comment = None;
48 if ctx.match_token(TokenKind::Comment) {
49 comment = Some(ctx.expect_string_literal()?);
50 }
51 defs.push(PropertyDef {
52 name,
53 data_type: dtype,
54 nullable,
55 default,
56 comment,
57 serial,
58 });
59 if !ctx.match_token(TokenKind::Comma) {
60 break;
61 }
62 }
63 ctx.expect_token(TokenKind::RParen)?;
64 }
65 Ok(defs)
66 }
67
68 fn parse_value_literal(&mut self, ctx: &mut ParseContext) -> Result<Value, ParseError> {
69 let token_kind = ctx.current_token().kind.clone();
70
71 if matches!(token_kind, TokenKind::Identifier(_))
72 && ctx.peek_token().kind == TokenKind::LParen
73 {
74 return self.parse_and_eval_function_call(ctx);
75 }
76
77 match token_kind {
78 TokenKind::StringLiteral(s) => {
79 ctx.next_token();
80 Ok(Value::string(s))
81 }
82 TokenKind::IntegerLiteral(n) => {
83 ctx.next_token();
84 Ok(Value::BigInt(n))
85 }
86 TokenKind::FloatLiteral(f) => {
87 ctx.next_token();
88 Ok(Value::Double(f))
89 }
90 TokenKind::BooleanLiteral(b) => {
91 ctx.next_token();
92 Ok(Value::Bool(b))
93 }
94 TokenKind::Null => {
95 ctx.next_token();
96 Ok(Value::Null(NullType::Null))
97 }
98 TokenKind::Minus => {
99 ctx.next_token();
100 let inner_token_kind = ctx.current_token().kind.clone();
101 match inner_token_kind {
102 TokenKind::IntegerLiteral(n) => {
103 ctx.next_token();
104 Ok(Value::BigInt(-n))
105 }
106 TokenKind::FloatLiteral(f) => {
107 ctx.next_token();
108 Ok(Value::Double(-f))
109 }
110 _ => Err(ParseError::new(
111 ParseErrorKind::SyntaxError,
112 format!(
113 "Expected number after minus sign, found {:?}",
114 inner_token_kind
115 ),
116 ctx.current_position(),
117 )),
118 }
119 }
120 _ => Err(ParseError::new(
121 ParseErrorKind::SyntaxError,
122 format!("Unsupported default value type: {:?}", token_kind),
123 ctx.current_position(),
124 )),
125 }
126 }
127
128 fn parse_and_eval_function_call(
129 &mut self,
130 ctx: &mut ParseContext,
131 ) -> Result<Value, ParseError> {
132 let parse_result = parse_expression(ctx)?;
133
134 use crate::executor::expression::evaluation_context::DefaultExpressionContext;
135 use crate::executor::expression::evaluator::ExpressionEvaluator;
136
137 let mut eval_ctx = DefaultExpressionContext::new();
138 ExpressionEvaluator::evaluate(&parse_result.expr, &mut eval_ctx).map_err(|e| {
139 ParseError::new(
140 ParseErrorKind::SyntaxError,
141 format!("Failed to evaluate DEFAULT expression: {}", e),
142 ctx.current_position(),
143 )
144 })
145 }
146
147 pub(super) fn parse_single_property_def(
148 &mut self,
149 ctx: &mut ParseContext,
150 ) -> Result<PropertyDef, ParseError> {
151 let name = ctx.expect_identifier()?;
152 ctx.match_token(TokenKind::Colon);
153 let mut serial = false;
154 let dtype = if ctx.match_token(TokenKind::Serial) {
155 serial = true;
156 DataType::BigInt
157 } else {
158 self.parse_data_type(ctx)?
159 };
160 let mut nullable = true;
161 if ctx.check_token(TokenKind::Not) {
162 ctx.next_token();
163 if ctx.check_token(TokenKind::Null) {
164 ctx.next_token();
165 nullable = false;
166 }
167 } else if ctx.match_token(TokenKind::Null) {
168 nullable = true;
169 }
170 if serial {
171 nullable = false;
173 }
174 let mut default = None;
175 if ctx.match_token(TokenKind::Default) {
176 default = Some(self.parse_value_literal(ctx)?);
177 }
178 let mut comment = None;
179 if ctx.match_token(TokenKind::Comment) {
180 comment = Some(ctx.expect_string_literal()?);
181 }
182 Ok(PropertyDef {
183 name,
184 data_type: dtype,
185 nullable,
186 default,
187 comment,
188 serial,
189 })
190 }
191
192 pub(super) fn parse_vid_type_value(
193 &mut self,
194 ctx: &mut ParseContext,
195 ) -> Result<String, ParseError> {
196 let token = ctx.current_token();
197 match token.kind {
198 TokenKind::String => {
199 ctx.next_token();
200 Ok("STRING".to_string())
201 }
202 TokenKind::Int
203 | TokenKind::Int8
204 | TokenKind::Int16
205 | TokenKind::Int32
206 | TokenKind::Int64 => {
207 ctx.next_token();
208 Ok("INT64".to_string())
209 }
210 TokenKind::Float => {
211 ctx.next_token();
212 Ok("FLOAT".to_string())
213 }
214 TokenKind::Double => {
215 ctx.next_token();
216 Ok("DOUBLE".to_string())
217 }
218 TokenKind::FixedString => {
219 ctx.next_token();
220 if ctx.current_token().kind == TokenKind::LParen {
221 ctx.next_token();
222 if let TokenKind::IntegerLiteral(length) = ctx.current_token().kind {
223 let len = length;
224 ctx.next_token();
225 if ctx.current_token().kind == TokenKind::RParen {
226 ctx.next_token();
227 Ok(format!("FIXED_STRING({})", len))
228 } else {
229 Err(ParseError::new(
230 ParseErrorKind::SyntaxError,
231 "FIXED_STRING right parenthesis required".to_string(),
232 ctx.current_position(),
233 ))
234 }
235 } else {
236 Err(ParseError::new(
237 ParseErrorKind::SyntaxError,
238 "FIXED_STRING requires length parameter".to_string(),
239 ctx.current_position(),
240 ))
241 }
242 } else {
243 Ok("FIXED_STRING(32)".to_string())
244 }
245 }
246 TokenKind::Identifier(ref s) => {
247 let upper = s.to_uppercase();
248 match upper.as_str() {
249 "STRING" => {
250 ctx.next_token();
251 Ok("STRING".to_string())
252 }
253 "INT" | "INT8" | "INT16" | "INT32" | "INT64" => {
254 ctx.next_token();
255 Ok("INT64".to_string())
256 }
257 "FLOAT" => {
258 ctx.next_token();
259 Ok("FLOAT".to_string())
260 }
261 "DOUBLE" => {
262 ctx.next_token();
263 Ok("DOUBLE".to_string())
264 }
265 "VID" => {
268 ctx.next_token();
269 Ok("VID".to_string())
270 }
271 _ => {
272 let rest = upper
273 .strip_prefix("FIXED_STRING")
274 .or_else(|| upper.strip_prefix("FIXEDSTRING"));
275 match rest {
276 Some(trailing) if trailing.is_empty() => {
277 ctx.next_token();
278 if ctx.current_token().kind == TokenKind::LParen {
279 ctx.next_token();
280 if let TokenKind::IntegerLiteral(length) =
281 ctx.current_token().kind
282 {
283 if length <= 0 {
284 return Err(ParseError::new(
285 ParseErrorKind::SyntaxError,
286 "FIXED_STRING length must be a positive integer"
287 .to_string(),
288 ctx.current_position(),
289 ));
290 }
291 ctx.next_token();
292 if ctx.current_token().kind == TokenKind::RParen {
293 ctx.next_token();
294 Ok(format!("FIXED_STRING({})", length))
295 } else {
296 Err(ParseError::new(
297 ParseErrorKind::SyntaxError,
298 "FIXED_STRING right parenthesis required"
299 .to_string(),
300 ctx.current_position(),
301 ))
302 }
303 } else {
304 Err(ParseError::new(
305 ParseErrorKind::SyntaxError,
306 "FIXED_STRING requires length parameter".to_string(),
307 ctx.current_position(),
308 ))
309 }
310 } else {
311 Ok("FIXED_STRING(32)".to_string())
312 }
313 }
314 Some(trailing) => match trailing.parse::<i64>() {
315 Ok(length) if length > 0 => {
316 ctx.next_token();
317 Ok(format!("FIXED_STRING({})", length))
318 }
319 _ => Err(ParseError::new(
320 ParseErrorKind::SyntaxError,
321 format!(
322 "Invalid vid_type '{}'; supported vid types: INT64, STRING, FIXED_STRING(n)",
323 s
324 ),
325 ctx.current_position(),
326 )),
327 },
328 None => Err(ParseError::new(
329 ParseErrorKind::SyntaxError,
330 format!(
331 "Unknown vid_type '{}'; supported vid types: INT64, STRING, FIXED_STRING(n)",
332 s
333 ),
334 ctx.current_position(),
335 )),
336 }
337 }
338 }
339 }
340 _ => Err(ParseError::new(
341 ParseErrorKind::UnexpectedToken,
342 format!("Expected vid_type value, found {:?}", token.kind),
343 ctx.current_position(),
344 )),
345 }
346 }
347
348 pub fn parse_data_type(&mut self, ctx: &mut ParseContext) -> Result<DataType, ParseError> {
349 self.parse_data_type_inner(ctx, 0)
350 }
351
352 fn scalar_type_from_keyword(
356 &mut self,
357 ctx: &mut ParseContext,
358 canonical: &str,
359 ) -> Result<DataType, ParseError> {
360 ctx.next_token();
361 match canonical.parse::<DataType>() {
362 Ok(parsed) => Ok(parsed),
363 Err(e) => {
364 if let Some(resolved) = ctx.resolve_named_type(canonical) {
366 if resolved != DataType::Unknown {
367 return Ok(resolved);
368 }
369 }
370 Err(ParseError::new(
371 ParseErrorKind::SyntaxError,
372 format!("Unknown data type: {}", e.name),
373 ctx.current_position(),
374 ))
375 }
376 }
377 }
378
379 const MAX_COMPOSITE_TYPE_DEPTH: usize = 16;
382
383 fn parse_data_type_inner(
384 &mut self,
385 ctx: &mut ParseContext,
386 depth: usize,
387 ) -> Result<DataType, ParseError> {
388 let (dt, _extra) = self.parse_data_type_inner_ex(ctx, depth)?;
389 Ok(dt)
390 }
391
392 fn parse_data_type_inner_ex(
393 &mut self,
394 ctx: &mut ParseContext,
395 depth: usize,
396 ) -> Result<(DataType, bool), ParseError> {
397 let token = ctx.current_token();
398 match token.kind {
399 TokenKind::Struct => {
400 ctx.next_token();
401 if depth >= Self::MAX_COMPOSITE_TYPE_DEPTH {
402 return Err(ParseError::new(
403 ParseErrorKind::SyntaxError,
404 format!(
405 "STRUCT nesting exceeds the maximum depth of {}",
406 Self::MAX_COMPOSITE_TYPE_DEPTH
407 ),
408 ctx.current_position(),
409 ));
410 }
411 if !ctx.match_token(TokenKind::Lt) {
412 return Err(ParseError::new(
413 ParseErrorKind::SyntaxError,
414 "STRUCT requires '<' after keyword".to_string(),
415 ctx.current_position(),
416 ));
417 }
418 let mut fields = Vec::new();
419 let mut extra_gt = false;
420 loop {
421 let field_name = ctx.expect_identifier()?;
422 let (field_type, child_extra) =
423 self.parse_data_type_inner_ex(ctx, depth + 1)?;
424 extra_gt |= child_extra;
425 fields.push((field_name, field_type));
426 if extra_gt {
427 break;
428 }
429 if ctx.match_token(TokenKind::Comma) {
430 continue;
431 }
432 if ctx.match_token(TokenKind::Gt) {
433 break;
434 }
435 if ctx.check_token(TokenKind::ShiftRight) {
436 ctx.next_token();
437 extra_gt = true;
438 break;
439 }
440 return Err(ParseError::new(
441 ParseErrorKind::SyntaxError,
442 "STRUCT expects ',' or '>' between fields".to_string(),
443 ctx.current_position(),
444 ));
445 }
446 Ok((
447 DataType::Struct(Arc::new(StructTypeInfo::new(fields))),
448 extra_gt,
449 ))
450 }
451 TokenKind::Array => {
452 ctx.next_token();
453 if depth >= Self::MAX_COMPOSITE_TYPE_DEPTH {
454 return Err(ParseError::new(
455 ParseErrorKind::SyntaxError,
456 format!(
457 "ARRAY nesting exceeds the maximum depth of {}",
458 Self::MAX_COMPOSITE_TYPE_DEPTH
459 ),
460 ctx.current_position(),
461 ));
462 }
463 if !ctx.match_token(TokenKind::Lt) {
464 return Err(ParseError::new(
465 ParseErrorKind::SyntaxError,
466 "ARRAY requires '<' after keyword".to_string(),
467 ctx.current_position(),
468 ));
469 }
470 let (element, child_extra) = self.parse_data_type_inner_ex(ctx, depth + 1)?;
471 let mut extra_gt = child_extra;
472 if !extra_gt && !ctx.match_token(TokenKind::Gt) {
473 if ctx.check_token(TokenKind::ShiftRight) {
474 ctx.next_token();
475 extra_gt = true;
476 } else {
477 return Err(ParseError::new(
478 ParseErrorKind::SyntaxError,
479 "ARRAY expects '>' after element type".to_string(),
480 ctx.current_position(),
481 ));
482 }
483 }
484 let len = if ctx.match_token(TokenKind::LParen) {
485 if let TokenKind::IntegerLiteral(n) = ctx.current_token().kind {
486 ctx.next_token();
487 if !ctx.match_token(TokenKind::RParen) {
488 return Err(ParseError::new(
489 ParseErrorKind::SyntaxError,
490 "ARRAY length expects ')'".to_string(),
491 ctx.current_position(),
492 ));
493 }
494 Some(n as usize)
495 } else {
496 return Err(ParseError::new(
497 ParseErrorKind::SyntaxError,
498 "ARRAY length requires an integer".to_string(),
499 ctx.current_position(),
500 ));
501 }
502 } else {
503 None
504 };
505 Ok((
506 DataType::Array(Arc::new(ArrayTypeInfo::new(element, len))),
507 extra_gt,
508 ))
509 }
510 TokenKind::Identifier(ref s) if s.eq_ignore_ascii_case("DECIMAL") => {
511 ctx.next_token();
512 if !ctx.match_token(TokenKind::LParen) {
513 return Err(ParseError::new(
514 ParseErrorKind::SyntaxError,
515 "DECIMAL requires '(' after keyword".to_string(),
516 ctx.current_position(),
517 ));
518 }
519 let precision = match ctx.current_token().kind {
520 TokenKind::IntegerLiteral(n) => n as u8,
521 _ => {
522 return Err(ParseError::new(
523 ParseErrorKind::SyntaxError,
524 "DECIMAL precision must be an integer".to_string(),
525 ctx.current_position(),
526 ));
527 }
528 };
529 ctx.next_token();
530 if !ctx.match_token(TokenKind::Comma) {
531 return Err(ParseError::new(
532 ParseErrorKind::SyntaxError,
533 "DECIMAL requires ',' between precision and scale".to_string(),
534 ctx.current_position(),
535 ));
536 }
537 let scale = match ctx.current_token().kind {
538 TokenKind::IntegerLiteral(n) => n as u8,
539 _ => {
540 return Err(ParseError::new(
541 ParseErrorKind::SyntaxError,
542 "DECIMAL scale must be an integer".to_string(),
543 ctx.current_position(),
544 ));
545 }
546 };
547 ctx.next_token();
548 if !ctx.match_token(TokenKind::RParen) {
549 return Err(ParseError::new(
550 ParseErrorKind::SyntaxError,
551 "DECIMAL requires ')' after scale".to_string(),
552 ctx.current_position(),
553 ));
554 }
555 Ok((DataType::Decimal { precision, scale }, false))
556 }
557 TokenKind::Identifier(ref s) if s.eq_ignore_ascii_case("UNION") => {
558 ctx.next_token();
559 if !ctx.match_token(TokenKind::LParen) {
560 return Err(ParseError::new(
561 ParseErrorKind::SyntaxError,
562 "UNION requires '(' after keyword".to_string(),
563 ctx.current_position(),
564 ));
565 }
566 let mut types = Vec::new();
567 loop {
568 let t = self.parse_data_type_inner(ctx, depth + 1)?;
569 types.push(t);
570 if !ctx.match_token(TokenKind::Comma) {
571 break;
572 }
573 }
574 if !ctx.match_token(TokenKind::RParen) {
575 return Err(ParseError::new(
576 ParseErrorKind::SyntaxError,
577 "UNION requires ')' after types".to_string(),
578 ctx.current_position(),
579 ));
580 }
581 Ok((DataType::Union(types), false))
582 }
583 TokenKind::Int
584 | TokenKind::Int8
585 | TokenKind::Int16
586 | TokenKind::Int32
587 | TokenKind::Int64
588 | TokenKind::Float
589 | TokenKind::Double
590 | TokenKind::String
591 | TokenKind::Bool
592 | TokenKind::Date
593 | TokenKind::Time
594 | TokenKind::Timestamp
595 | TokenKind::Datetime
596 | TokenKind::Geography
597 | TokenKind::List
598 | TokenKind::Map
599 | TokenKind::Set
600 | TokenKind::UUID
601 | TokenKind::Text
602 | TokenKind::Null => {
603 let canonical = token.lexeme.to_ascii_uppercase();
604 Ok((self.scalar_type_from_keyword(ctx, &canonical)?, false))
605 }
606 TokenKind::FixedString => {
607 ctx.next_token();
608 if ctx.current_token().kind == TokenKind::LParen {
609 ctx.next_token();
610 if let TokenKind::IntegerLiteral(len) = ctx.current_token().kind {
611 let length = len as usize;
612 ctx.next_token();
613 if ctx.current_token().kind == TokenKind::RParen {
614 ctx.next_token();
615 Ok((DataType::FixedString(length), false))
616 } else {
617 Err(ParseError::new(
618 ParseErrorKind::SyntaxError,
619 "FIXED_STRING Right bracket required".to_string(),
620 ctx.current_position(),
621 ))
622 }
623 } else {
624 Err(ParseError::new(
625 ParseErrorKind::SyntaxError,
626 "FIXED_STRING Need length parameter".to_string(),
627 ctx.current_position(),
628 ))
629 }
630 } else {
631 Ok((DataType::FixedString(32), false))
632 }
633 }
634 TokenKind::KeywordVector => {
635 ctx.next_token();
636 if ctx.current_token().kind == TokenKind::LParen {
637 ctx.next_token();
638 if let TokenKind::IntegerLiteral(len) = ctx.current_token().kind {
639 let dimension = len as usize;
640 ctx.next_token();
641 if ctx.current_token().kind == TokenKind::RParen {
642 ctx.next_token();
643 Ok((DataType::VectorDense(dimension), false))
644 } else {
645 Err(ParseError::new(
646 ParseErrorKind::SyntaxError,
647 "VECTOR Right bracket required".to_string(),
648 ctx.current_position(),
649 ))
650 }
651 } else {
652 Err(ParseError::new(
653 ParseErrorKind::SyntaxError,
654 "VECTOR requires dimension parameter".to_string(),
655 ctx.current_position(),
656 ))
657 }
658 } else {
659 Ok((DataType::Vector, false))
660 }
661 }
662 TokenKind::Identifier(ref s) => {
663 let type_name = s.clone();
664 ctx.next_token();
665 match type_name.to_uppercase().as_str() {
666 "FIXED_STRING" | "FIXEDSTRING" => {
667 if ctx.current_token().kind == TokenKind::LParen {
668 ctx.next_token();
669 if let TokenKind::IntegerLiteral(len) = ctx.current_token().kind {
670 let length = len as usize;
671 ctx.next_token();
672 if ctx.current_token().kind == TokenKind::RParen {
673 ctx.next_token();
674 Ok((DataType::FixedString(length), false))
675 } else {
676 Err(ParseError::new(
677 ParseErrorKind::SyntaxError,
678 "FIXED_STRING Right bracket required".to_string(),
679 ctx.current_position(),
680 ))
681 }
682 } else {
683 Err(ParseError::new(
684 ParseErrorKind::SyntaxError,
685 "FIXED_STRING Need length parameter".to_string(),
686 ctx.current_position(),
687 ))
688 }
689 } else {
690 Ok((DataType::FixedString(32), false))
691 }
692 }
693 "VECTOR" => {
694 if ctx.current_token().kind == TokenKind::LParen {
695 ctx.next_token();
696 if let TokenKind::IntegerLiteral(len) = ctx.current_token().kind {
697 let dimension = len as usize;
698 ctx.next_token();
699 if ctx.current_token().kind == TokenKind::RParen {
700 ctx.next_token();
701 Ok((DataType::VectorDense(dimension), false))
702 } else {
703 Err(ParseError::new(
704 ParseErrorKind::SyntaxError,
705 "VECTOR Right bracket required".to_string(),
706 ctx.current_position(),
707 ))
708 }
709 } else {
710 Err(ParseError::new(
711 ParseErrorKind::SyntaxError,
712 "VECTOR requires dimension parameter".to_string(),
713 ctx.current_position(),
714 ))
715 }
716 } else {
717 Ok((DataType::Vector, false))
718 }
719 }
720 _ => {
725 let parsed = match type_name.parse::<DataType>() {
726 Ok(parsed) => parsed,
727 Err(e) => match ctx.resolve_named_type(&type_name) {
728 Some(resolved) if resolved != DataType::Unknown => resolved,
729 _ => {
730 return Err(ParseError::new(
731 ParseErrorKind::SyntaxError,
732 format!("Unknown data type: {}", e.name),
733 ctx.current_position(),
734 ));
735 }
736 },
737 };
738 Ok((parsed, false))
739 }
740 }
741 }
742 _ => Err(ParseError::new(
743 ParseErrorKind::UnexpectedToken,
744 format!("Expected data type, discovered {:?}", token.kind),
745 ctx.current_position(),
746 )),
747 }
748 }
749}