@@ -802,55 +802,83 @@ may then be further optimized by selecting better implementations of each operat
802
802
)
803
803
)
804
804
805
+ (with statement
806
+ (exclude dml)
807
+ (include
808
+ // An `INSERT` DML operation, which is fundamentally different from UPDATE and DELETE
809
+ // because it lacks a FROM and WHERE clause while also including an ON CONFLICT clause.
810
+ //
811
+ // Models: INSERT INTO <dml_target> [AS <target_alias>] <rows_to_insert> [<on-conflict>]
812
+ (dml_insert
813
+ // The target is an expression indicates the table whose data is to be manipulated.
814
+ // With current PartiQL Parser `SqlParser`, this can be an identifier or a simplified path expression
815
+ // consisting of only literal path steps (and with no wildcard or unpivot operators).
816
+ // Note: partiql_ast uses the `expr` sum type for this, which is too broad. We're not
817
+ // changing that at this time because `partiql_ast` is established public API, but we can
818
+ // use dml_target instead which has the properly narrowed domain.
819
+ (target dml_target)
820
+ (target_alias var_decl)
821
+ (rows_to_insert expr)
822
+ (on_conflict (? on_conflict))
823
+ )
824
+
825
+ // Models: UPDATE <dml_target> [AS <target_alias>] SET <assignments> [WHERE <where>]
826
+ (dml_update
827
+ (target dml_target)
828
+ (target_alias var_decl)
829
+ (assignments (* set_assignment 0))
830
+ (where (? expr))
831
+ )
832
+
833
+ // Models DELETE <from>
834
+ (dml_delete (from bexpr)) // note: the bexpr includes filters, etc.
835
+ )
836
+ )
837
+
805
838
(include
806
- // Indicates kind of DML operation.
807
- (sum dml_operation
808
- (dml_insert target_alias::var_decl)
809
- (dml_delete)
810
-
811
- // Represents the REPLACE statement as well as INSERT ... ON CONFLICT DO REPLACE ...
812
- // [target-alias]: represents the alias for the table name. See the following syntactical example:
813
- // `INSERT INTO Table1 AS <alias> << { 'id': 1, 'name': 'Arash' } >> ON CONFLICT DO REPLACE ...`
814
- // [condition]: represents the condition by which a row should be replaced. See the following syntactical example:
815
- // `INSERT INTO x << {'id': 1, 'name': 'John'}} >> ON CONFLICT DO REPLACE EXCLUDED WHERE <condition>`
816
- // [row_alias]: represents the alias given to the rows meant to be inserted/replaced. It is made optional
817
- // since dml_replace is currently shared by REPLACE (which does not allow the aliasing of rows) and
818
- // INSERT ... ON CONFLICT DO REPLACE ... (which aliases the rows as "EXCLUDED" for use within the [condition]).
819
- (dml_replace target_alias::var_decl condition::(? expr) row_alias::(? var_decl))
820
-
821
- // Represents the UPSERT statement as well as INSERT ... ON CONFLICT DO UPDATE ...
822
- // [target-alias]: represents the alias for the table name. See the following syntactical example:
823
- // `INSERT INTO Table1 AS <alias> << { 'id': 1, 'name': 'Arash' } >> ON CONFLICT DO UPDATE ...`
824
- // [condition]: represents the condition by which a row should be replaced. See the following syntactical example:
825
- // `INSERT INTO x << {'id': 1, 'name': 'John'}} >> ON CONFLICT DO UPDATE EXCLUDED WHERE <condition>`
826
- // [row_alias]: represents the alias given to the rows meant to be inserted/updated. It is made optional
827
- // since dml_update is currently shared by UPSERT (which does not allow the aliasing of rows) and
828
- // INSERT ... ON CONFLICT DO UPDATE ... (which aliases the rows as "EXCLUDED" for use within the [condition]).
829
- (dml_update target_alias::var_decl condition::(? expr) row_alias::(? var_decl))
839
+ // represents simple paths, i.e. suitable for the left side of an `=` operator within a `SET` clause.
840
+ // Example `a_field.nested_field[42]`
841
+ (record simple_path
842
+ // The first element, `a_field` in the example above.
843
+ (root identifier)
844
+ // The subsequent elements, `nested_field` and `[42]` in the example above.
845
+ (steps (* simple_path_step 0))
846
+ )
847
+ (sum simple_path_step
848
+ // for bracket paths steps, i.e. `[42]` in the simple_path example above.
849
+ (sps_index (index int))
850
+ // for symbols, i.e. `nested_field` in the simple_path example above.
851
+ (sps_identifier (identifier identifier))
830
852
)
831
- )
832
853
833
- // Redefine statement.dml to be a simpler subset of the full DML functionality expressed with PartiQL's DML
834
- // syntax. Full functionality is out of scope for now. This is factored minimally to support
835
- // `INSERT INTO` and `DELETE FROM ... [WHERE <predicate>]` but this may need refactoring when
836
- // `FROM ... UPDATE` and `UPDATE` is supported later.
837
- (with statement
838
- (exclude dml)
839
- (include
840
- // A DML operation, such as `INSERT`, `UPDATE` or `DELETE`
841
- (dml
842
- // The target is an expression that is indicates the table whose data is to be manipulated.
843
- // With current PartiQL Parser `SqlParser`, this can be an identifier or a simplified path expression
844
- // consisting of only literal path steps (and with no wildcard or unpivot operators).
845
- // Note: partiql_ast uses the `expr` sum type for this, which is too broad. We're not
846
- // changing that at this time because `partiql_ast` is established public API.
847
- target::identifier
848
- operation::dml_operation
849
- rows::expr
850
- )
854
+ // The "target" of a DML operation, i.e. the table targeted for manipulation with INSERT, UPDATE, etc.
855
+ // This is a discrete type so it can be permuted in later domains to affect every use.
856
+ (record dml_target (identifier identifier))
857
+
858
+ // An assignment within a SET clause.
859
+ (record set_assignment
860
+ // The target, left of `=`
861
+ (set_target simple_path)
862
+ // The new value for the target, right of `=`
863
+ (value expr)
851
864
)
865
+
866
+ // INSERT's ON CONFLICT Clause
867
+ (record on_conflict
868
+ (excluded_alias var_decl)
869
+ (condition (? expr))
870
+ (action on_conflict_action)
871
+ )
872
+
873
+ (sum on_conflict_action
874
+ (do_update)
875
+ (do_replace)
876
+ )
877
+
852
878
)
853
879
880
+
881
+
854
882
// Nodes excluded below this line will eventually have a representation in the logical algebra, but not
855
883
// initially.
856
884
@@ -934,11 +962,9 @@ may then be further optimized by selecting better implementations of each operat
934
962
)
935
963
)
936
964
937
- // Replace statement.dml.target with statement.dml.uniqueId (the "resolved" corollary).
938
- (with statement
939
- (exclude dml)
940
- (include (dml uniqueId::symbol operation::dml_operation rows::expr))
941
- )
965
+ // Replace statement.dml.uniqueId (the "resolved" corollary).
966
+ (exclude dml_target)
967
+ (include (record dml_target (uniqueId symbol)))
942
968
)
943
969
)
944
970
0 commit comments