Skip to content

Allow preconditions to be enabled via the Artifact plugin  #1047

@predictiple

Description

@predictiple

Related to issue #930

The current behaviour for artifacts called by the Artifact plugin is that preconditions are disabled. This means that artifacts that are designed to be called from other artifacts have to be written and tested with this limitation in mind.

If the called artifact needs to implement conditional behaviour equivalent to multiple sources with a precondition for each source, then this has to be done using the switch() and if() functions in one block of VQL. This is far less visually comprehensible than an artifact with multiple sources with a precondition for each source, especially if viewing the artifact in a text editor that doesn't do VQL syntax highlighting.

If preconditions are only possible on top-level artifacts then this encourages the development of monolithic/standalone artifacts and discourages modular artifact development, and therefore discourages code reusability.

As an example consider this artifact that uses preconditions:

parameters:
  - name: foo
    type: bool
    default: true

sources:

  - name: A
    precondition: SELECT log(message="precondition A") FROM scope() WHERE foo
    query: SELECT "A ran" AS message FROM scope()

  - name: B
    precondition: SELECT log(message="precondition B") FROM scope() WHERE NOT foo
    query: SELECT "B ran" AS message FROM scope()

  - name: C
    precondition: SELECT log(message="precondition C") FROM scope()
    query: SELECT "C ran" AS message FROM scope()

If the above artifact needs to be called from another artifact then it has to be written thusly:

parameters:
  - name: foo
    type: bool
    default: true

sources:

  - name: AorBandC
    query: |
      SELECT * FROM chain(
        x={ SELECT * FROM switch(
            a={ SELECT *
                FROM if(condition={ SELECT log(message="precondition A") 
                                      FROM scope() WHERE foo },
                      then={ SELECT "A ran" AS message FROM scope() } ) },
            b={ SELECT *
                FROM if(condition={ SELECT log(message="precondition B") 
                                      FROM scope() WHERE NOT foo },
                      then={ SELECT "B ran" AS message FROM scope() } ) }
            )},
        c={ SELECT *
            FROM if(condition={ SELECT log(message="precondition C") 
                                  FROM scope() },
                  then={ SELECT "C ran" AS message FROM scope() } ) }
        )

The 2nd version is obviously far less comprehensible, even though it's still a relatively simple artifact (in the real world I have far more complicated artifacts) 🤮

I would like to propose that we allow preconditions to be optionally enabled when calling an artifact via the Artifact plugin. This option could be presented to the user as a new argument on the Artifact plugin, for example:
SELECT * FROM Artifact.Foo.Bar(preconditions=enabled)

The current behaviour of disabling preconditions in called artifacts could be preserved by making preconditions=disabled the default for the Artifact plugin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions