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
181 changes: 176 additions & 5 deletions crates/oxabl_ast/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ pub enum Statement {
/// Define input/output params
DefineParameter {
direction: ParameterDirection,
name: Identifier,
data_type: DataType,
no_undo: bool,
param_type: ParameterType,
},

/// RUN statement — executes an internal procedure or external `.p` file.
Expand Down Expand Up @@ -182,6 +180,8 @@ pub enum Statement {
fields: Vec<TempTableField>,
/// Index definitions.
indexes: Vec<TempTableIndex>,
/// XML and serialization options (NAMESPACE-URI, SERIALIZE-NAME, etc.).
xml_options: XmlSerializeOptions,
},

/// DEFINE BUFFER statement.
Expand All @@ -197,6 +197,8 @@ pub enum Statement {
preselect: bool,
/// Optional label for error messages.
label: Option<String>,
/// XML and serialization options (NAMESPACE-URI, SERIALIZE-NAME, etc.).
xml_options: XmlSerializeOptions,
},

/// CATCH block within a DO/REPEAT/FOR block.
Expand Down Expand Up @@ -363,8 +365,11 @@ pub enum Statement {
type_name: String,
},

/// CREATE buffer-name [NO-ERROR].
Create { buffer: Identifier, no_error: bool },
/// CREATE statement — record creation or dynamic object creation.
Create {
target: CreateTarget,
no_error: bool,
},

/// DELETE buffer-name [NO-ERROR].
Delete { buffer: Identifier, no_error: bool },
Expand Down Expand Up @@ -415,6 +420,39 @@ pub enum Statement {
/// Simplified: captures name and raw span of unparsed content for formatter round-tripping.
DefineFrame { name: Identifier, raw_span: Span },

/// DEFINE DATASET statement.
///
/// ```abl
/// DEFINE DATASET dsPerson FOR ttPerson, ttAddress
/// DATA-RELATION drPersonAddr FOR ttPerson, ttAddress
/// RELATION-FIELDS (personId, personId).
/// ```
DefineDataset {
name: Identifier,
access: Option<AccessModifier>,
is_static: bool,
is_new_shared: bool, // TODO: Retrofit on DefineTempTable, DefineBuffer, VariableDeclaration
is_shared: bool, // TODO: Retrofit on DefineTempTable, DefineBuffer, VariableDeclaration
serializable: bool,
non_serializable: bool,
xml_options: XmlSerializeOptions,
reference_only: bool,
buffers: Vec<Identifier>,
data_relations: Vec<DataRelation>,
parent_id_relations: Vec<ParentIdRelation>,
},

/// DEFINE DATA-SOURCE statement.
///
/// `DEFINE DATA-SOURCE dsCustomer FOR Customer.`
DefineDataSource {
name: Identifier,
access: Option<AccessModifier>,
is_static: bool,
query: Option<Identifier>,
source_buffers: Vec<DataSourceBuffer>,
},

/// INPUT/OUTPUT/INPUT-OUTPUT stream I/O statement.
StreamIo {
direction: StreamDirection,
Expand Down Expand Up @@ -632,3 +670,136 @@ pub struct AssignPair {
/// The value to assign.
pub value: Expression,
}

// =============================================================================
// XML / Serialize options (shared across TEMP-TABLE, BUFFER, DATASET)
// =============================================================================

/// XML and serialization options shared by TEMP-TABLE, BUFFER, and DATASET definitions.
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct XmlSerializeOptions {
pub namespace_uri: Option<Identifier>,
pub namespace_prefix: Option<Identifier>,
pub xml_node_name: Option<Identifier>,
pub xml_node_type: Option<Identifier>,
pub serialize_name: Option<Identifier>,
pub serialize_hidden: bool,
}

// =============================================================================
// Dataset types
// =============================================================================

/// A DATA-RELATION clause in a DEFINE DATASET statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataRelation {
pub name: Option<Identifier>,
pub parent_buffer: Identifier,
pub child_buffer: Identifier,
/// Pairs of (parent_field, child_field) from RELATION-FIELDS.
pub relation_fields: Vec<(Identifier, Identifier)>,
pub reposition: bool,
pub nested: bool,
pub foreign_key_hidden: bool,
pub not_active: bool,
pub recursive: bool,
}

/// A PARENT-ID-RELATION clause in a DEFINE DATASET statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParentIdRelation {
pub name: Option<Identifier>,
pub parent_buffer: Identifier,
pub child_buffer: Identifier,
pub id_field: Identifier,
pub parent_fields_before: Vec<Identifier>,
pub parent_fields_after: Vec<Identifier>,
}

// =============================================================================
// Data-source types
// =============================================================================

/// A source buffer phrase in a DEFINE DATA-SOURCE statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataSourceBuffer {
pub name: Identifier,
pub keys: Option<DataSourceKeys>,
}

/// KEYS clause in a DATA-SOURCE source buffer phrase.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DataSourceKeys {
/// KEYS (field1, field2, ...)
Fields(Vec<Identifier>),
/// KEYS (ROWID)
Rowid,
}

// =============================================================================
// CREATE target types
// =============================================================================

/// Target of a CREATE statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CreateTarget {
/// CREATE buffer-name — record creation or any unrecognized CREATE.
Name(Identifier),
/// CREATE DATASET/DATA-SOURCE/TEMP-TABLE handle [IN WIDGET-POOL pool].
Handle {
kind: CreateTargetKind,
handle: Identifier,
widget_pool: Option<Expression>,
},
}

/// The type keyword in a CREATE ... handle statement.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CreateTargetKind {
Dataset,
DataSource,
TempTable,
}

// =============================================================================
// Parameter types
// =============================================================================

/// The type/shape of a DEFINE PARAMETER statement.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParameterType {
/// Standard variable parameter: DEFINE INPUT PARAMETER name AS type [NO-UNDO].
Variable {
name: Identifier,
data_type: DataType,
no_undo: bool,
},
/// Handle-based parameter: TABLE/TABLE-HANDLE/DATASET/DATASET-HANDLE
Handle {
kind: HandleParamKind,
name: Identifier,
passing: HandlePassingOptions,
},
/// Buffer parameter: DEFINE PARAMETER BUFFER buf FOR table.
Buffer {
name: Identifier,
target: Identifier,
},
}

/// Discriminant for handle-based parameter types.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HandleParamKind {
Table,
TableHandle,
Dataset,
DatasetHandle,
}

/// Passing options for handle-based parameters (APPEND, BIND, BY-VALUE).
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct HandlePassingOptions {
pub append: bool,
pub bind: bool,
pub by_value: bool,
}
25 changes: 25 additions & 0 deletions crates/oxabl_lexer/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,15 @@ fn main() {
"bell",
"between",
"big endian",
"bind",
"blank",
"blob",
"break",
"buffer",
"buffer-compare",
"buffer-copy",
"by",
"by-value",
"call",
"can do",
"can find",
Expand Down Expand Up @@ -140,10 +142,13 @@ fn main() {
"data rel",
"data relation",
"data source",
"data-relation",
"data-source",
"database",
"dataservers",
"dataset",
"dataset handle",
"dataset-handle",
"date",
"datetime",
"datetime-tz",
Expand Down Expand Up @@ -229,6 +234,7 @@ fn main() {
"focus",
"font",
"for",
"foreign-key-hidden",
"form",
"format",
"fram",
Expand Down Expand Up @@ -355,7 +361,10 @@ fn main() {
"modulo",
"mouse",
"mpe",
"namespace-prefix",
"namespace-uri",
"ne",
"nested",
"new",
"next",
"next-prompt",
Expand All @@ -381,7 +390,9 @@ fn main() {
"no-val",
"no-validate",
"no-wait",
"non-serializable",
"not",
"not-active",
"now",
"null",
"num-ali",
Expand Down Expand Up @@ -416,6 +427,10 @@ fn main() {
"page-top",
"param",
"parameter",
"parent-fields-after",
"parent-fields-before",
"parent-id-field",
"parent-id-relation",
"password-field",
"pause",
"pdbname",
Expand Down Expand Up @@ -469,6 +484,9 @@ fn main() {
"recid",
"rect",
"rectangle",
"recursive",
"reference-only",
"relation-fields",
"release",
"repeat",
"reposition",
Expand Down Expand Up @@ -510,6 +528,9 @@ fn main() {
"seek",
"select",
"self",
"serializable",
"serialize-hidden",
"serialize-name",
"session",
"set",
"set-attr-call-type",
Expand All @@ -531,6 +552,7 @@ fn main() {
"stream-io",
"system-dialog",
"table",
"table-handle",
"table-number",
"temp-table",
"term",
Expand Down Expand Up @@ -581,6 +603,7 @@ fn main() {
"when",
"where",
"while",
"widget-pool",
"window",
"window-maxim",
"window-maximized",
Expand All @@ -594,6 +617,8 @@ fn main() {
"workfile",
"write",
"xcode",
"xml-node-name",
"xml-node-type",
"xref",
"xref-xml",
"yes",
Expand Down
Loading